Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6150 was 6150, checked in by bensch, 18 years ago

orxonox/trunk: cleanup of the world begin

File size: 9.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, EV_MAIN_QUIT);          //< External Quit Event
92  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_QUIT);
93  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_NEXT_WORLD);
94  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_PREVIOUS_WORLD);
95}
96
97
98/**
99 *  reads a campaign definition file into a campaign class
100 * @param fileName to be loaded
101 * @returns the loaded campaign
102 *
103 * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
104 */
105ErrorMessage GameLoader::loadCampaign(const char* fileName)
106{
107  ErrorMessage errorCode;
108  char* campaignName = ResourceManager::getFullName(fileName);
109  if (campaignName)
110    {
111      this->currentCampaign = this->fileToCampaign(campaignName);
112      delete[] campaignName;
113    }
114}
115
116
117/**
118 *  reads a campaign definition file into a campaign class
119 * @param fileName to be loaded
120 * @returns the loaded campaign
121 *
122 * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
123 */
124ErrorMessage GameLoader::loadNetworkCampaign(const char* fileName)
125{
126  ErrorMessage errorCode;
127  char* campaignName = ResourceManager::getFullName(fileName);
128  if (campaignName)
129  {
130    this->currentCampaign = this->fileToNetworkCampaign(campaignName);
131    delete[] campaignName;
132  }
133}
134
135
136/**
137 *  loads a debug campaign for test purposes only.
138 * @param campaignID the identifier of the campaign.
139 * @returns error message if not able to do so.
140 */
141ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
142{
143  switch(campaignID)
144    {
145      /*
146         Debug Level 0: Debug level used to test the base frame work.
147         As you can see, all storyentity data is allocated before game
148         start. the storyentity will load themselfs shortly before start
149         through the StoryEntity::init() funtion.
150      */
151    case DEBUG_CAMPAIGN_0:
152      {
153        // FIXME
154/*        Campaign* debugCampaign = new Campaign();
155
156        World* world0 = new World(DEBUG_WORLD_0);
157        world0->setNextStoryID(WORLD_ID_1);
158        debugCampaign->addEntity(world0, WORLD_ID_0);
159
160        World* world1 = new World(DEBUG_WORLD_1);
161        world1->setNextStoryID(WORLD_ID_2);
162        debugCampaign->addEntity(world1, WORLD_ID_1);
163
164        World* world2 = new World(DEBUG_WORLD_2);
165        world2->setNextStoryID(WORLD_ID_GAMEEND);
166        debugCampaign->addEntity(world2, WORLD_ID_2);
167
168        this->currentCampaign = debugCampaign;
169        break;*/
170      }
171    }
172}
173
174
175/**
176 *  starts the current entity
177 * @returns error code if this action has caused a error
178 */
179ErrorMessage GameLoader::start()
180{
181  if(this->currentCampaign != NULL)
182    this->currentCampaign->start();
183}
184
185
186/**
187 *  stops the current entity
188 * @returns error code if this action has caused a error
189 *
190 *  ATTENTION: this function shouldn't call other functions, or if so, they must return
191 *  after finishing. If you ignore or forget to do so, the current entity is not able to
192 *  terminate and it will run in the background or the ressources can't be freed or even
193 *  worse: are freed and the program will end in a segmentation fault!
194 *  hehehe, have ya seen it... :)
195 */
196void GameLoader::stop()
197{
198  if(this->currentCampaign != NULL)
199    this->currentCampaign->stop();
200}
201
202
203/**
204 *  pause the current entity
205 * @returns error code if this action has caused a error
206 *
207 * this pauses the current entity or passes this call forth to the running entity.
208 */
209ErrorMessage GameLoader::pause()
210{
211  this->isPaused = true;
212  if(this->currentCampaign != NULL)
213    this->currentCampaign->pause();
214}
215
216
217/**
218 *  resumes a pause
219 * @returns error code if this action has caused a error
220 *
221 *  this resumess the current entity or passes this call forth to the running entity.
222 */
223ErrorMessage GameLoader::resume()
224{
225  this->isPaused = false;
226  if(this->currentCampaign != NULL)
227    this->currentCampaign->resume();
228}
229
230
231/**
232 *  release the mem ATTENTION: not implemented
233 */
234ErrorMessage GameLoader::destroy()
235{
236
237}
238
239
240/**
241 *  reads a campaign definition file into a campaign class
242 * @param fileName to be loaded
243 * @returns the loaded campaign
244 *
245 * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
246 */
247Campaign* GameLoader::fileToCampaign(const char* fileName)
248{
249  /* do not entirely load the campaign. just the current world
250     before start of each world, it has to be initialized so it
251     can load everything it needs into memory then.
252  */
253
254  if( fileName == NULL)
255    {
256      PRINTF(2)("No filename specified for loading");
257      return NULL;
258    }
259
260  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
261  // load the campaign document
262  if( !XMLDoc->LoadFile())
263    {
264      // report an error
265      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
266      delete XMLDoc;
267      return NULL;
268    }
269
270  // check basic validity
271  TiXmlElement* root = XMLDoc->RootElement();
272  assert( root != NULL);
273
274  if( strcmp( root->Value(), "Campaign"))
275    {
276      // report an error
277      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
278      delete XMLDoc;
279      return NULL;
280    }
281
282  // construct campaign
283  Campaign* c = new Campaign( root);
284
285  // free the XML data
286  delete XMLDoc;
287
288  return c;
289}
290
291
292/**
293 *  reads a campaign definition file into a campaign class
294 * @param fileName to be loaded
295 * @returns the loaded campaign
296 *
297 *  this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
298 */
299Campaign* GameLoader::fileToNetworkCampaign(const char* fileName)
300{
301  /* do not entirely load the campaign. just the current world
302  before start of each world, it has to be initialized so it
303  can load everything it needs into memory then.
304  */
305
306  if( fileName == NULL)
307  {
308    PRINTF(2)("No filename specified for loading");
309    return NULL;
310  }
311
312  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
313  // load the campaign document
314  if( !XMLDoc->LoadFile())
315  {
316      // report an error
317    PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
318    delete XMLDoc;
319    return NULL;
320  }
321
322  // check basic validity
323  TiXmlElement* root = XMLDoc->RootElement();
324  assert( root != NULL);
325
326  if( strcmp( root->Value(), "Campaign"))
327  {
328      // report an error
329    PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
330    delete XMLDoc;
331    return NULL;
332  }
333
334  // construct campaign
335  Campaign* c = new Campaign( root);
336
337  // free the XML data
338  delete XMLDoc;
339
340  return c;
341}
342
343
344/**
345 *  handle keyboard commands
346 * @param event the event to handle
347 */
348void GameLoader::process(const Event& event)
349{
350  if( event.type == KeyMapper::PEV_NEXT_WORLD)
351  {
352    if( likely(event.bPressed))
353    {
354      this->nextLevel();
355    }
356  }
357  else if( event.type == KeyMapper::PEV_PREVIOUS_WORLD)
358  {
359    if( likely(event.bPressed))
360    {
361      this->previousLevel();
362    }
363  }
364  else if( event.type == KeyMapper::PEV_PAUSE)
365  {
366    if( likely(event.bPressed))
367    {
368      if(this->isPaused)
369        this->resume();
370      else
371        this->pause();
372    }
373  }
374  else if( event.type == KeyMapper::PEV_QUIT)
375  {
376    if( event.bPressed) this->stop();
377  }
378  else if (event.type == EV_MAIN_QUIT)
379    this->stop();
380}
381
382
383/**
384 *  \brief this changes to the next level
385 */
386void GameLoader::nextLevel()
387{
388  if(this->currentCampaign != NULL)
389    this->currentCampaign->nextLevel();
390}
391
392
393/**
394 *  change to the previous level - not implemented
395 *
396 * this propably useless
397 */
398void GameLoader::previousLevel()
399{
400  if(this->currentCampaign != NULL)
401    this->currentCampaign->previousLevel();
402}
Note: See TracBrowser for help on using the repository browser.