Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/orxonox.cc @ 3668

Last change on this file since 3668 was 3668, checked in by patrick, 20 years ago

orxonox/trunk: made list more performant and less vulnerable to segfaults. changed the benchmark function to only display list attributes for now. changed pnode to iterator

File size: 15.5 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software Foundation,
18   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
19
20
21   ### File Specific:
22   main-programmer: Patrick Boenzli
23   co-programmer: Christian Meyer
24   co-programmer: Benjamin Grauer: injected ResourceManager/GraphicsEngine
25*/
26
27#include "orxonox.h"
28
29#include "world.h"
30#include "data_tank.h"
31#include "command_node.h"
32#include "game_loader.h"
33#include "graphics_engine.h"
34#include "resource_manager.h"
35
36#include <string.h>
37int verbose = 3;
38
39using namespace std;
40
41/**
42   \brief create a new Orxonox
43*/
44Orxonox::Orxonox ()
45{
46  pause = false;
47}
48
49/**
50   \brief remove Orxonox from memory
51*/
52Orxonox::~Orxonox () 
53{
54  Orxonox::singletonRef = NULL;
55  if( world != NULL) delete world;
56  if( localinput != NULL) delete world;
57  if( resources != NULL) delete resources;
58  delete GraphicsEngine::getInstance(); // deleting the Graphics
59  delete ResourceManager::getInstance(); // deletes the Resource Manager
60}
61
62/** \brief this is a singleton class to prevent duplicates */
63Orxonox* Orxonox::singletonRef = 0;
64
65/**
66   \returns reference or new Object of Orxonox if not existent.
67*/
68Orxonox* Orxonox::getInstance (void)
69{
70  if (singletonRef == NULL)
71    singletonRef = new Orxonox();
72  return singletonRef;
73}
74
75/**
76   \brief this finds the config file
77   
78   Since the config file varies from user to user and since one may want to specify different config files
79   for certain occasions or platforms this function finds the right config file for every occasion and stores
80   it's path and name into configfilename
81*/
82void Orxonox::getConfigFile (int argc, char** argv)
83{
84  strcpy (configfilename, "orxonox.conf");
85}
86
87/**
88   \brief initialize Orxonox with command line
89*/
90int Orxonox::init (int argc, char** argv)
91{
92  // parse command line
93  // config file
94 
95  getConfigFile (argc, argv);
96  SDL_Init (SDL_INIT_TIMER);
97  // initialize everything
98  if( initVideo() == -1) return -1;
99  if( initSound() == -1) return -1;
100  printf("> Initializing input\n");
101  if( initInput() == -1) return -1;
102  printf("> Initializing networking\n");
103  if( initNetworking () == -1) return -1;
104  printf("> Initializing resources\n");
105  if( initResources () == -1) return -1;
106  //printf("> Initializing world\n");
107  //if( init_world () == -1) return -1; PB: world will be initialized when started
108 
109  return 0;
110}
111
112/**
113   \brief initializes SDL and OpenGL
114*/
115int Orxonox::initVideo() 
116{
117  PRINTF(3)("> Initializing video\n");
118 
119  GraphicsEngine::getInstance();
120 
121  return 0;
122}
123
124
125/**
126   \brief initializes the sound engine
127*/
128int Orxonox::initSound() 
129{
130  printf("> Initializing sound\n");
131  // SDL_Init(SDL_INIT_AUDIO);
132  printf("Not yet implemented\n");
133  return 0;
134}
135
136
137/**
138   \brief initializes input functions
139*/
140int Orxonox::initInput() 
141{
142  // create localinput
143  localinput = new CommandNode( configfilename);
144 
145  return 0;
146}
147
148
149/**
150   \brief initializes network system
151*/
152int Orxonox::initNetworking() 
153{
154  printf("Not yet implemented\n");
155  return 0;
156}
157
158
159/**
160   \brief initializes and loads resource files
161*/
162int Orxonox::initResources() 
163{
164  //  printf("Not yet implemented\n");
165  PRINT(3)("initializing ResourceManager\n");
166  resourceManager = ResourceManager::getInstance();
167  resourceManager->setDataDir("../data/");
168  return 0;
169}
170
171
172/**
173   \brief initializes the world
174*/
175int Orxonox::initWorld() 
176{
177  //world = new World();
178 
179  // TO DO: replace this with a menu/intro
180  //world->load_debug_level();
181 
182  return 0;
183}
184
185
186/**
187   \brief starts the orxonox game or menu
188
189   here is the central orxonox state manager. There are currently two states
190   - menu
191   - game-play
192   both states manage their states themselfs again.
193*/
194void Orxonox::start()
195{
196 
197  this->gameLoader = GameLoader::getInstance();
198  this->gameLoader->loadDebugCampaign(DEBUG_CAMPAIGN_0);
199  this->gameLoader->init();
200  this->gameLoader->start();
201}
202
203
204/**
205   \brief exits Orxonox
206*/
207void Orxonox::quitGame() 
208{
209  bQuitOrxonox = true;
210}
211
212
213
214/**
215   \brief handles sprecial events from localinput
216   \param event: an event not handled by the CommandNode
217*/
218void Orxonox::eventHandler(SDL_Event* event)
219{
220  // Handle special events such as reshape, quit, focus changes
221  switch (event->type)
222    {
223    case SDL_VIDEORESIZE:
224      GraphicsEngine* tmpGEngine = GraphicsEngine::getInstance();
225      tmpGEngine->resolutionChanged(&event->resize);
226      break;
227    }
228}
229 
230
231/**
232   \brief handle keyboard commands that are not meant for WorldEntities
233   \param cmd: the command to handle
234   \return true if the command was handled by the system or false if it may be passed to the WorldEntities
235*/
236bool Orxonox::systemCommand(Command* cmd)
237{
238  /*
239  if( !strcmp( cmd->cmd, "quit"))
240    {
241      if( !cmd->bUp) this->gameLoader->stop();
242      return true;
243    }
244  return false;
245  */
246  return false;
247}
248
249/**
250   \brief retrieve a pointer to the local CommandNode
251   \return a pointer to localinput
252*/
253CommandNode* Orxonox::getLocalInput()
254{
255  return localinput;
256}
257
258
259/**
260   \brief retrieve a pointer to the local World
261   \return a pointer to world
262*/
263World* Orxonox::getWorld()
264{
265  return world;
266}
267
268/**
269   \return The reference of the SDL-screen of orxonox
270*/
271SDL_Surface* Orxonox::getScreen ()
272{
273  return this->screen;
274}
275
276
277
278/**
279   \brief main function
280
281   here the journey begins
282*/
283int main(int argc, char** argv) 
284{ 
285 
286  /* reading arguments
287     
288     currently supported arguments are:
289     <no args>                   ::    just starts orxonox
290     --benchmark                 ::    start the benchmark without starting orxonox
291     
292     this is a preselection: it matches to one of the start* functions, the
293     finetuning is made in those functions.
294  */
295
296
297  int i;
298  for(i = 0; i < argc; ++i)
299    {
300      if(! strcmp( "--help", argv[i])) return startHelp();
301      else if(! strcmp( "--benchmark", argv[i])) return startBenchmarks();
302    }
303
304  PRINTF(2)("Orxonox does not understand the arguments");
305  return startOrxonox(argc, argv);
306}
307
308
309
310int startHelp()
311{
312  printf("orxonox: starts the orxonox game - rules\n");
313  printf("usage: orxonox [arg]\n\n");
314  printf("valid options:\n");
315  printf(" --benchmark\tstarts the orxonox benchmark\n");
316  printf(" --help \tshows this menu\n");
317}
318
319
320int startOrxonox(int argc, char** argv)
321{
322  printf(">>> Starting Orxonox <<<\n");
323  Orxonox *orx = Orxonox::getInstance();
324 
325  if((*orx).init(argc, argv) == -1)
326    {
327      printf("! Orxonox initialization failed\n");
328      return -1;
329    }
330 
331  orx->start();
332 
333  //  delete orx;
334 
335}
336
337
338#include "list.h"
339#include "world_entity.h"
340#include "vector.h"
341#include "player.h"
342#include "base_object.h"
343#include "primitive.h"
344#include <asm/msr.h>
345#include <linux/timex.h>
346
347
348#define LIST_MAX 1000
349#define VECTOR_MAX 1000000
350#define ITERATIONS 10000
351
352
353int startBenchmarks()
354{
355
356  printf("===========================================================\n");
357  printf("=                      BENCHMARKS                         =\n");
358  printf("===========================================================\n");
359  printf(" the author is not paying any attention to cacheing effects\n");
360  printf(" of the CPU.\n\n");
361  printf("[title]\t\t\t\t\t     [cycles]\t[loops]\n\n");
362  //  printf("------------------------------------------------------------\n\n");
363
364  // first measure the time overhead:
365  unsigned long ini, end, dt, tmp;
366  rdtscl(ini); rdtscl(end);
367  dt = end - ini;
368
369  int type = 3; 
370  /* type   -1 == all
371     type    0 == framework
372     type    1 == vector
373     type    2 == quaternion
374     type    3 == lists
375  */
376  if(type == 0 || type == -1)
377    {
378      /* framework test*/
379     
380      printf("Generating Objects:\t\t\t\t\t%i\n", ITERATIONS);
381      /* ************WorldEntity class test************** */
382      WorldEntity* w = NULL;
383      int i = 0;
384      unsigned long mittel = 0;
385     
386      for(i = 0; i < ITERATIONS; ++i)
387        {
388          rdtscl(ini);
389         
390          WorldEntity* w = new WorldEntity();
391         
392          rdtscl(end);
393          delete w;
394          mittel += (end - ini - dt);
395        }
396      float mi = mittel / (float)ITERATIONS;
397      printf(" Generate a WorldEntity object:\t\t%11.2f\n", mi);
398     
399      mittel = 0;
400      for(i = 0; i < ITERATIONS; ++i)
401        {
402          rdtscl(ini);
403         
404          WorldEntity* w = new Primitive(P_SPHERE);
405         
406          rdtscl(end);
407          delete w;
408          mittel += (end - ini - dt);
409        }
410      mi = mittel / (float)ITERATIONS;
411      printf(" Generate a Primitive  object:\t\t%11.2f\n", mi);
412
413
414      mittel = 0;
415      for(i = 0; i < ITERATIONS; ++i)
416        {
417          rdtscl(ini);
418         
419          Vector* v = new Vector();
420         
421          rdtscl(end);
422          delete v;
423          mittel += (end - ini - dt);
424        }
425      mi = mittel / (float)ITERATIONS;
426      printf(" Generate a Vector object:\t\t%11.2f\n", mi);
427
428
429     mittel = 0;
430      for(i = 0; i < ITERATIONS; ++i)
431        {
432          rdtscl(ini);
433         
434          Quaternion* q = new Quaternion();
435         
436          rdtscl(end);
437          delete q;
438          mittel += (end - ini - dt);
439        }
440      mi = mittel / (float)ITERATIONS;
441      printf(" Generate a Quaternion object:\t\t%11.2f\n", mi);
442
443
444
445
446      printf("\nCalling function inline &| virtual, \t\t\t%i\n", ITERATIONS);
447      mittel = 0;
448      w = new WorldEntity();
449      for(i = 0; i < ITERATIONS; ++i)
450        {
451          rdtscl(ini);
452         
453          w->tick(0.0f);
454
455          rdtscl(end);
456          mittel += (end - ini - dt);
457          }
458      //delete w;
459      mi = mittel / (float)ITERATIONS;
460      printf(" Virt funct tick() of WE: \t\t%11.2f\n", mi);
461
462
463      mittel = 0;
464      WorldEntity wo;
465      for(i = 0; i < ITERATIONS; ++i)
466        {
467          rdtscl(ini);
468         
469          wo.tick(0.0f);
470           
471          rdtscl(end);
472          mittel += (end - ini - dt);
473          }
474      //delete w;
475      mi = mittel / (float)ITERATIONS;
476      printf(" Inl virt funct tick() of WE v2: \t%11.2f\n", mi);
477
478     
479      mittel = 0;
480      BaseObject* bo = new BaseObject();
481      for(i = 0; i < ITERATIONS; ++i)
482        {
483          rdtscl(ini);
484         
485          bo->isFinalized();
486           
487          rdtscl(end);
488          mittel += (end - ini - dt);
489          }
490      //delete w;
491      mi = mittel / (float)ITERATIONS;
492      printf(" Inl funct BaseObject::isFinazlized(): \t%11.2f\n", mi);
493
494     
495      tList<WorldEntity>* list = new tList<WorldEntity>();
496
497     
498      /* ************Primitvie class test************** */
499      list = new tList<WorldEntity>();
500 
501     
502     
503      mittel = 0;
504      w = new Primitive(P_SPHERE);
505      for(i = 0; i < ITERATIONS; ++i)
506        {
507          rdtscl(ini);
508         
509          w->tick(0.0f);
510           
511          rdtscl(end);
512          mittel += (end - ini - dt);
513        }
514      mi = mittel / (float)ITERATIONS;
515      printf(" Call function tick() of Prim:\t\t%11.2f\n", mi);
516     
517     
518    }
519 
520  if(type == 1 || type == -1)
521    {
522      printf("\nDoing some simple vector operations: \t\t\t%i\n", VECTOR_MAX);
523      /* vector test */
524      Vector* a = new Vector(1.3, 5.3, 4.1);
525      Vector* b = new Vector(0.4, 2.5, 6.2);
526      Vector* c = new Vector();
527     
528      unsigned long mittel, ini, end;
529      float mi;
530      int i = 0;
531      // addition
532      mittel = 0;
533      for(i = 0; i < VECTOR_MAX; ++i)
534        {
535          rdtscl(ini);
536         
537          *c = *a + *b;
538           
539          rdtscl(end);
540          mittel += (end - ini - dt);
541        }
542      mi = mittel / (float)VECTOR_MAX;
543      printf(" Addition of two vectors:\t\t%11.2f\n", mi);
544     
545      // multiplikation
546
547      mittel = 0;
548      for(i = 0; i < VECTOR_MAX; ++i)
549        {
550          rdtscl(ini);
551         
552          *c = a->cross( *b);
553           
554          rdtscl(end);
555          mittel += (end - ini - dt);
556        }
557      mi = mittel / (float)VECTOR_MAX;
558      printf(" CrossMult of two vectors:\t\t%11.2f\n", mi);
559
560    }
561  if( type == 2 || type == -1)
562    {
563      /* quaternion test */
564      printf("\nDoing some simple quaternion operations: \t\t%i\n", VECTOR_MAX);
565      /* vector test */
566      Quaternion* a = new Quaternion();
567      Quaternion* b = new Quaternion();
568      Quaternion* c = new Quaternion();
569     
570      unsigned long mittel, ini, end;
571      float mi;
572      int i = 0;
573      // quaternion generieren mit spez konstruktor
574      mittel = 0;
575      Vector* qa = new Vector(4.6, 9.3, 0.4);
576      Vector* qb = new Vector(3.5, 6.1, 4.3);
577      for(i = 0; i < VECTOR_MAX; ++i)
578        {
579          rdtscl(ini);
580         
581          Quaternion* qu = new Quaternion(*qa, *qb);
582         
583          rdtscl(end);
584          delete qu;
585          mittel += (end - ini - dt);
586        }
587      delete a;
588      delete b;
589      mi = mittel / (float)VECTOR_MAX;
590      printf(" Gen. quatern. betw. two vectors:\t%11.2f\n", mi);
591     
592     
593      // multiplication
594      mittel = 0;
595      for(i = 0; i < VECTOR_MAX; ++i)
596        {
597          rdtscl(ini);
598         
599          *c = *a * *b;
600         
601          rdtscl(end);
602          mittel += (end - ini - dt);
603        }
604      mi = mittel / (float)VECTOR_MAX;
605      printf(" Multiplying two quat.(=rot): a * b\t%11.2f\n", mi);
606     
607     
608     
609      // rotating a vector by a quaternion
610      mittel = 0;
611      for(i = 0; i < VECTOR_MAX; ++i)
612        {
613          rdtscl(ini);
614         
615          *qa = a->apply(*qb);
616         
617          rdtscl(end);
618          mittel += (end - ini - dt);
619        }
620      mi = mittel / (float)VECTOR_MAX;
621      printf(" Rot a vec by a quat: q->apply(v)\t%11.2f\n", mi);
622     
623     
624     
625      // generate rotation matrix
626      mittel = 0;
627      float matrix[4][4];
628      for(i = 0; i < VECTOR_MAX; ++i)
629        {
630          rdtscl(ini);
631         
632          a->matrix(matrix);
633         
634          rdtscl(end);
635          mittel += (end - ini - dt);
636        }
637      mi = mittel / (float)VECTOR_MAX;
638      printf(" Generate rot matrix: q->matrix(m)\t%11.2f\n", mi);
639    }
640  if( type == 3 || type == -1)
641    {
642      /* list tests*/
643      printf("\nList operations tests: \t\t\t\t\t%i\n", LIST_MAX);
644      tList<char>* list = new tList<char>();
645      char* name;
646     
647      printf(" Adding[1..10] elements to list, found:\n");
648      list->add("1");
649      list->add("2");
650      list->add("3");
651      list->add("4");
652      list->add("5");
653      list->add("6");
654      list->add("7");
655      list->add("8");
656      list->add("9");
657      list->add("10");
658     
659      /*give list out */
660      tIterator<char>* iterator = list->getIterator();
661      name = iterator->nextElement();
662      printf("  List Elements: \t\t");
663      while( name != NULL)
664        {
665          printf("%s,", name);
666          name = iterator->nextElement();
667        }
668      delete iterator;
669      printf("\n");
670     
671     
672      /*removing some elements from the list*/
673      printf(" Removing elements [2,3,6,8,10], adding [11] now found:\n");
674      list->remove("2");
675      list->remove("3");
676      list->remove("6");
677      list->remove("8");
678      list->remove("10");
679      list->add("11");
680      /*give list out */
681      iterator = list->getIterator();
682      name = iterator->nextElement();
683      printf("  List Elements: \t\t");
684      while( name != NULL)
685        {
686          printf("%s,", name);
687          name = iterator->nextElement();
688        }
689      delete iterator;
690      printf("\n");
691     
692      delete list;
693      printf("\nChecking list performance:\t\t\t\t%i\n", LIST_MAX);
694     
695      tList<int>* plist = new tList<int>();
696      unsigned long mittel, ini, end;
697      float mi;
698      int i = 0;
699      mittel = 0;
700      for(i = 0; i < LIST_MAX; ++i)
701        {
702          rdtscl(ini);
703         
704          plist->add(&i);
705         
706          rdtscl(end);
707          mittel += (end - ini - dt);
708        }
709      mi = mittel / (float)LIST_MAX;
710      printf(" Adding reference to list:\t\t%11.2f\n", mi);
711     
712      mittel = 0;
713      for(i = 0; i < LIST_MAX; ++i)
714        {
715          rdtscl(ini);
716         
717          plist->remove(&i);
718         
719          rdtscl(end);
720          mittel += (end - ini - dt);
721        }
722      mi = mittel / (float)LIST_MAX;
723      printf(" Removing 1st reference from list:\t%11.2f\n", mi);
724     
725     
726     
727    }
728 
729}
Note: See TracBrowser for help on using the repository browser.