Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cleanup/src/orxonox.cc @ 10609

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

cleaned out unused defs files, and moved glincl to grafics, alincl.h to sound

File size: 16.8 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#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ORXONOX
28#include "orxonox.h"
29
30#include "orxonox_globals.h"
31
32#include "gui/qt/qt_gui.h"
33#include "gui/qt/qt_gui_datadir_fallback.h"
34
35#include "parser/ini_parser/ini_parser.h"
36#include "util/loading/game_loader.h"
37#include "util/signal_handler.h"
38
39//ENGINES
40#include "graphics_engine.h"
41#include "sound_engine.h"
42#include "util/loading/resource_manager.h"
43
44#include "cd_engine.h"
45#include "event_handler.h"
46
47#include "loading/fast_factory.h"
48
49#include "shell_command_class.h"
50#include "shell_command.h"
51
52#include "network_manager.h"
53#include "shared_network_data.h"
54
55#include "state.h"
56#include "lib/parser/preferences/cmd_line_prefs_reader.h"
57#include "lib/parser/preferences/ini_file_prefs_reader.h"
58#include <string.h>
59
60int verbose = 5;
61
62
63
64SHELL_COMMAND(restart, Orxonox, restart);
65
66REGISTER_ARG_FLAG( l, license,    "misc",  "showLicenseAndExit", "Prints the license and exit",      "1" );
67REGISTER_ARG_FLAG( c, client,     "game",  "gameType",           "Connect to Server (-H)",           "multiplayer_client" );
68REGISTER_ARG_FLAG( s, server,     "game",  "gameType",           "Start Orxonox as Game Server",     "multiplayer_master_server" );
69REGISTER_ARG_FLAG( x, proxy,      "game",  "gameType",           "Start Orxonox as Proxy Server",    "multiplayer_proxy_server" );
70REGISTER_ARG_ARG(  H, host,       "game",  "host",               "Host to connect to",               "host");
71REGISTER_ARG_ARG(  p, port,       "game",  "port",               "Port to use",                      "port" );
72REGISTER_ARG_FLAG( g, gui,        "game",  "showGui",            "starts the orxonox with the configuration GUI", "1");
73
74REGISTER_ARG_FLAG( f, fullscreen, "video", "Fullscreen-mode",    "start Orxonox in fullscreen mode", "1");
75REGISTER_ARG_FLAG( w, windowed,   "video", "Fullscreen-mode",    "start Orxonox in windowed mode",   "0");
76REGISTER_ARG_ARG(  r, resolution, "video", "Resolution",         "sets resolution / window size",    "res");
77REGISTER_ARG_FLAG( d, dedicated,  "video", "Norender-mode",      "the scene is not rendered",        "1" );
78
79REGISTER_ARG_FLAG( a, audio,      "audio", "Disable-Audio",      "Enable audio",                     "0" );
80REGISTER_ARG_FLAG( m, mute ,      "audio", "Disable-Audio",      "Disable audio",                    "1" );
81REGISTER_ARG_ARG(  _, audio_channels, "audio", "Audio-Channels", "Sets # audio channels", "num" );
82REGISTER_ARG_ARG(  _, music_volume, "audio", "Music-Volume", "Sets music volume", "vol" );
83REGISTER_ARG_ARG(  _, effects_volume, "audio", "Effects-Volume", "Sets effects volume", "vol" );
84
85#ifndef __WIN32__
86REGISTER_ARG_FLAG( _, write_bt_to_file, "misc", "bt-to-file", "Write backtrace to file", "1");
87REGISTER_ARG_FLAG( _, dont_catch_signals, "misc", "bt-to-file", "Write backtrace to file", "0");
88#endif
89
90REGISTER_ARG_ARG(  t, telnetport,  "network","telnetport",        "Port to use for network debug output",               "port" );
91REGISTER_ARG_ARG(  _, write_dict,  "compression", "writedict",    "write packets to DATA/dicts/newdict",               "numBytes" );
92
93ObjectListDefinition(Orxonox);
94
95/**
96 *  create a new Orxonox
97
98   In this funcitons only global values are set. The game will not be started here.
99*/
100Orxonox::Orxonox ()
101{
102  this->registerObject(this, Orxonox::_objectList);
103  this->setName("orxonox-main");
104
105  this->argc = 0;
106  this->argv = NULL;
107
108  /* this way, there is no network enabled: */
109  this->serverName = "";
110  this->port = -1;
111
112  this->configFileName = "";
113}
114
115/**
116 *  remove Orxonox from memory
117*/
118Orxonox::~Orxonox ()
119{
120  // game-specific
121  delete GameLoader::getInstance();
122
123  // class-less services/factories
124  FastFactory::deleteAll();
125  OrxShell::ShellCommandClass::unregisterAllCommands();
126
127  // handlers
128  Resources::ResourceManager::deleteInstance(); // deletes the Resource Manager
129
130  // engines
131  delete CDEngine::getInstance();
132  delete OrxSound::SoundEngine::getInstance();
133  delete GraphicsEngine::getInstance(); // deleting the Graphics
134  delete EventHandler::getInstance();
135
136  Resources::ResourceManager::deleteInstance();
137  // output-buffer
138  delete DebugBuffer::getInstance();
139
140  SDL_QuitSubSystem(SDL_INIT_TIMER);
141
142
143  ObjectListBase::debugAll(1);
144
145  Preferences::getInstance()->save();
146
147  PRINT(3)
148  (
149    "===================================================\n" \
150    "Thanks for playing orxonox.\n" \
151    "visit: http://www.orxonox.net for new versions.\n" \
152    "===================================================\n" \
153    ORXONOX_LICENSE_SHORT
154  );
155
156  Orxonox::singletonRef = NULL;
157}
158
159/**
160 *  this is a singleton class to prevent duplicates
161 */
162Orxonox* Orxonox::singletonRef = NULL;
163
164// DANGEROUS
165void Orxonox::restart()
166{
167  //   int argc = this->argc;
168  //   char** argv = this->argv;
169  //
170  //   Orxonox *orx = Orxonox::getInstance();
171  //
172  //   delete orx;
173  //
174  //   orx = Orxonox::getInstance();
175  //
176  //   if((*orx).init(argc, argv) == -1)
177  //   {
178  //     PRINTF(1)("! Orxonox initialization failed\n");
179  //     return;
180  //   }
181  //
182  //   printf("finished inizialisation\n");
183  //   orx->start();
184}
185
186/**
187 * @brief this finds the config file
188 * @returns the new config-fileName
189 * Since the config file varies from user to user and since one may want to specify different config files
190 * for certain occasions or platforms this function finds the right config file for every occasion and stores
191 * it's path and name into configfilename
192*/
193const std::string& Orxonox::getConfigFile ()
194{
195  File orxConfFile("orxonox.conf");
196  if (orxConfFile.isFile())
197  {
198    this->configFileName =  "orxonox.conf";
199  }
200  else
201    this->configFileName = File(DEFAULT_CONFIG_FILE).name();
202
203  PRINTF(3)("Parsed Config File: '%s'\n", this->configFileName.c_str());
204  return this->configFileName;
205}
206
207/**
208 * initialize Orxonox with command line
209 */
210int Orxonox::init (int argc, char** argv, const std::string & name, int port)
211{
212  this->argc = argc;
213  this->argv = argv;
214
215  this->serverName = name;
216  this->port = port;
217
218  // initialize the Config-file
219  this->getConfigFile();
220
221  // windows must not write into stdout.txt and stderr.txt
222  /*#ifdef __WIN32__
223  freopen( "CON", "w", stdout );
224  freopen( "CON", "w", stderr );
225  #endif*/
226
227  // initialize everything
228  SDL_Init(0);
229  if( initResources () == -1)
230    return -1;
231  if( initVideo() == -1)
232    return -1;
233  if( initSound() == -1)
234    return -1;
235  if( initInput() == -1)
236    return -1;
237  if( initNetworking () == -1)
238    return -1;
239  if( initMisc () == -1)
240    return -1;
241
242  return 0;
243}
244
245
246/**
247 * initializes SDL and OpenGL
248 */
249int Orxonox::initVideo()
250{
251  PRINTF(3)("> Initializing video\n");
252
253  GraphicsEngine::getInstance();
254
255  GraphicsEngine::getInstance()->initFromPreferences();
256
257  std::string iconName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath("textures/fighter-top-32x32.bmp");
258  if (!iconName.empty())
259  {
260    GraphicsEngine::getInstance()->setWindowName(PACKAGE_NAME " " PACKAGE_VERSION, iconName);
261  }
262  return 0;
263}
264
265
266/**
267 * initializes the sound engine
268 */
269int Orxonox::initSound()
270{
271  PRINT(3)("> Initializing sound\n");
272  // SDL_InitSubSystem(SDL_INIT_AUDIO);
273  OrxSound::SoundEngine::getInstance();
274
275  OrxSound::SoundEngine::getInstance()->loadSettings();
276  OrxSound::SoundEngine::getInstance()->initAudio();
277  return 0;
278}
279
280
281/**
282 * initializes input functions
283 */
284int Orxonox::initInput()
285{
286  PRINT(3)("> Initializing input\n");
287
288  EventHandler::getInstance()->init();
289  EventHandler::getInstance()->subscribe(GraphicsEngine::getInstance(), ES_ALL, EV_VIDEO_RESIZE);
290
291  return 0;
292}
293
294
295/**
296 * initializes network system
297 */
298int Orxonox::initNetworking()
299{
300  PRINT(3)("> Initializing networking\n");
301  std::string gameType = Preferences::getInstance()->getString( "game", "gameType", "" );
302
303  if( gameType == "multiplayer_client")
304  {    // we are a client
305    State::setOnline(true);
306    SharedNetworkData::getInstance()->setNodeType(NET_CLIENT);
307    NetworkManager::getInstance()->createClient(this->serverName, port);
308  }
309  else if( gameType == "multiplayer_master_server")
310  {    // we are a master server
311    State::setOnline(true);
312    SharedNetworkData::getInstance()->setNodeType(NET_MASTER_SERVER);
313
314    NetworkManager::getInstance()->createMasterServer(port);
315  }
316  else if( gameType == "multiplayer_proxy_server")
317  {    // we are a proxy server
318    State::setOnline(true);
319    SharedNetworkData::getInstance()->setNodeType(NET_PROXY_SERVER_ACTIVE);
320    NetworkManager::getInstance()->createProxyServer(port);
321  }
322
323  return 0;
324
325}
326
327//#include "util/loading/dynamic_loader.h"
328/**
329 * initializes and loads resource files
330 */
331int Orxonox::initResources()
332{
333  PRINTF(3)("> Initializing resources\n");
334
335  PRINT(3)("initializing ResourceManager\n");
336
337  // init the resource manager
338  std::string dataPath = Preferences::getInstance()->getString(CONFIG_SECTION_GENERAL, CONFIG_NAME_DATADIR, "");
339  if (dataPath!= "")
340  {
341    Resources::ResourceManager::getInstance()->setMainGlobalPath(dataPath) ;
342    if(!Resources::ResourceManager::getInstance()->checkFileInMainPath(File(DEFAULT_DATA_DIR_CHECKFILE)))
343    {
344      PRINTF(1)("Data Could not be located in %s\n", dataPath.c_str());
345    }
346  }
347  while (!Resources::ResourceManager::getInstance()->checkFileInMainPath(File(DEFAULT_DATA_DIR_CHECKFILE)))
348  {
349
350    PRINTF(1)("The DataDirectory %s could not be verified\n\nh" \
351              "!!!  Please Change in File %s Section %s Entry %s to a suitable value !!!\n",
352              Resources::ResourceManager::getInstance()->mainGlobalPath().name().c_str(),
353              this->configFileName.c_str(),
354              CONFIG_SECTION_GENERAL,
355              CONFIG_NAME_DATADIR );
356    OrxGui::Gui* gui = new OrxGui::QtGuiDataDirFallback(argc, argv);
357    gui->startGui();
358    if (gui->getState() == OrxGui::Gui::Quitting)
359      return(-1);
360    delete gui;
361    Resources::ResourceManager::getInstance()->setMainGlobalPath(Preferences::getInstance()->getString(CONFIG_SECTION_GENERAL, CONFIG_NAME_DATADIR, ""));
362  }
363
364  //! @todo this is a hack and should be loadable
365  Resources::ResourceManager::getInstance()->addResourceSubPath("Texture", "textures");
366  //Resources::ResourceManager::getInstance()->addResourceSubPath("Texture", "pictures");
367
368  Resources::ResourceManager::getInstance()->addResourceSubPath("SoundBuffer", "sounds");
369  Resources::ResourceManager::getInstance()->addResourceSubPath("SoundBuffer", "music");
370
371  Resources::ResourceManager::getInstance()->addResourceSubPath("Shader", "shaders");
372  Resources::ResourceManager::getInstance()->addResourceSubPath("OBJ", "models");
373
374  Resources::ResourceManager::getInstance()->addKeepLevelName("Imediately");
375  Resources::ResourceManager::getInstance()->addKeepLevelName("LevelEnd");
376  Resources::ResourceManager::getInstance()->addKeepLevelName("CampaignEnd");
377  Resources::ResourceManager::getInstance()->addKeepLevelName("GameEnd");
378  Resources::ResourceManager::getInstance()->setDefaultKeepLevel(std::string("GameEnd"));
379
380  return 0;
381}
382
383/**
384 * initializes miscelaneous features
385 * @return -1 on failure
386 */
387int Orxonox::initMisc()
388{
389  DebugBuffer::getInstance();
390
391  // start the collision detection engine
392  CDEngine::getInstance();
393
394  return 0;
395}
396
397/**
398 *  starts the orxonox game or menu
399 * here is the central orxonox state manager. There are currently two states
400 * - menu
401 * - game-play
402 * both states manage their states themselfs again.
403*/
404void Orxonox::start()
405{
406
407  this->gameLoader = GameLoader::getInstance();
408
409  if( this->port != -1)
410    this->gameLoader->loadNetworkCampaign("levels/DefaultNetworkCampaign.oxc");
411  else
412    this->gameLoader->loadCampaign("levels/DefaultCampaign.oxc");                       /* start orxonox in single player mode */
413
414  //  this->gameLoader->loadDebugCampaign(DEBUG_CAMPAIGN_0);
415  this->gameLoader->init();
416  this->gameLoader->start();
417}
418
419
420/**
421 * handles sprecial events from localinput
422 * @param event: an event not handled by the CommandNode
423 */
424// void Orxonox::graphicsHandler(SDL_Event* event)
425// {
426//   // Handle special events such as reshape, quit, focus changes
427//   switch (event->type)
428//     {
429//     case SDL_VIDEORESIZE:
430//       GraphicsEngine* tmpGEngine = GraphicsEngine::getInstance();
431//       tmpGEngine->resolutionChanged(event->resize);
432//       break;
433//     }
434// }
435
436
437
438
439
440
441bool showGui = false;
442
443/**********************************
444*** ORXONOX MAIN STARTING POINT ***
445**********************************/
446/**
447 *
448 *  main function
449 *
450 * here the journey begins
451*/
452int main(int argc, char** argv)
453{
454  CmdLinePrefsReader prefs;
455
456  // create the ~/.orxonox directory if there is not already one
457  Directory home("~/.orxonox");
458  if (!home.exists())
459    home.create();
460
461  IniFilePrefsReader ini(File(DEFAULT_CONFIG_FILE).name());
462  Preferences::getInstance()->setUserIni(File(DEFAULT_CONFIG_FILE).name());
463
464  prefs.parse(argc, argv);
465
466  if ( Preferences::getInstance()->getString("misc", "showLicenseAndExit", "") == "1" )
467  {
468    PRINT(0)(ORXONOX_LICENSE_SHORT);
469    return 0;
470  }
471
472  if ( Preferences::getInstance()->getString("misc", "bt-to-file", "1") == "1" )
473  {
474    SignalHandler::getInstance()->doCatch( argv[0], "orxonox.backtrace" );
475    SignalHandler::getInstance()->registerCallback( EventHandler::releaseMouse, NULL );
476  }
477
478  if( Preferences::getInstance()->getString("game", "showGui", "") == "1" )
479    showGui = true;
480  else if( Preferences::getInstance()->getString( "game", "gameType", "" ) == "multiplayer_master_server" ||
481           Preferences::getInstance()->getString( "game", "gameType", "" ) == "multiplayer_proxy_server" ||
482           Preferences::getInstance()->getString( "game", "gameType", "" ) == "multiplayer_client" )
483    return startNetworkOrxonox(argc, argv);
484
485  return startOrxonox(argc, argv, "", -1);
486}
487
488
489
490/**
491 * starts orxonox in network mode
492 * @param argc parameters count given to orxonox
493 * @param argv parameters given to orxonox
494 */
495int startNetworkOrxonox(int argc, char** argv)
496{
497
498  std::string gameType = Preferences::getInstance()->getString( "game", "gameType", "" );
499
500  if ( gameType == "multiplayer_client" )
501  {
502    int port = Preferences::getInstance()->getInt( "game", "port", DEFAULT_ORXONOX_PORT );
503    std::string host = Preferences::getInstance()->getString( "game", "host", "" );
504
505    if ( host == "" )
506    {
507      printf("You need to specify a host to connect to ( -H <host> )\n");
508      return 1;
509    }
510
511    printf("Starting Orxonox as client: connecting to %s, on port %i\n", host.c_str(), port);
512
513    startOrxonox(argc, argv, host.c_str(), port);
514  }
515  else if ( gameType == "multiplayer_master_server" )
516  {
517    int port = Preferences::getInstance()->getInt( "game", "port", DEFAULT_ORXONOX_PORT );
518
519    printf("Starting Orxonox as server: listening on port %i\n", port);
520
521    startOrxonox(argc, argv, "", port);
522  }
523  else if ( gameType == "multiplayer_proxy_server" )
524  {
525    int port = Preferences::getInstance()->getInt( "game", "port", DEFAULT_ORXONOX_PORT );
526
527    printf("Starting Orxonox as proxy server: listening on port %i\n", port);
528
529    startOrxonox(argc, argv, "", port);
530  }
531  return 1;
532}
533
534
535
536/**
537 * starts orxonox
538 * @param argc parameters count given to orxonox
539 * @param argv parameters given to orxonox
540 */
541int startOrxonox(int argc, char** argv, const std::string & name, int port)
542{
543  // checking for existence of the configuration-files, or if the lock file is still used
544  if (showGui || (!File("./orxonox.conf").isFile() &&
545                  !File(DEFAULT_CONFIG_FILE).isFile())
546#if DEBUG_LEVEL <= 3 // developers do not need to see the GUI, when orxonox fails
547      || ResourceManager::isFile(DEFAULT_LOCK_FILE)
548#endif
549     )
550  {
551    File lockFile(DEFAULT_LOCK_FILE);
552    if (lockFile.isFile())
553      lockFile.remove();
554
555    // starting the GUI
556    OrxGui::QtGui gui(argc, argv);
557    gui.startGui();
558
559    if (gui.getState() & OrxGui::Gui::Quitting)
560      return 0;
561
562  }
563
564  PRINT(0)(">>> Starting Orxonox <<<\n");
565
566  File(DEFAULT_LOCK_FILE).touch();
567
568  Orxonox *orx = Orxonox::getInstance();
569
570  if( orx->init(argc, argv, name, port) == -1)
571  {
572    PRINTF(1)("! Orxonox initialization failed\n");
573    return -1;
574  }
575
576  PRINTF(5)("finished inizialisation\n");
577  orx->start();
578
579  delete orx;
580  File("~/.orxonox/orxonox.lock").remove();
581  return 0;
582}
Note: See TracBrowser for help on using the repository browser.