Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: orxonox now runs from anywhere of the LINUX environment

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