/stk-code-master/src/main.cpp

https://github.com/jeremiejig/paf-autostereoscopie-2014 · C++ · 1622 lines · 1233 code · 126 blank · 263 comment · 340 complexity · c82c788ed20692938917acf8736a6cb7 MD5 · raw file

Large files are truncated click here to view the full file

  1. //
  2. // SuperTuxKart - a fun racing game with go-kart
  3. // Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
  4. // Copyright (C) 2011-2013 Joerg Henrichs, Marianne Gagnon
  5. //
  6. // This program is free software; you can redistribute it and/or
  7. // modify it under the terms of the GNU General Public License
  8. // as published by the Free Software Foundation; either version 3
  9. // of the License, or (at your option) 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
  18. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. /**
  20. * \mainpage SuperTuxKart developer documentation
  21. *
  22. * This document contains the developer documentation for SuperTuxKart,
  23. * including the list of modules, the list of classes, the API reference,
  24. * and some pages that describe in more depth some parts of the code/engine.
  25. *
  26. * \section Overview
  27. *
  28. * Here is an overview of the high-level interactions between modules :
  29. \dot
  30. digraph interaction {
  31. race -> modes
  32. race -> tracks
  33. race -> karts
  34. modes -> tracks
  35. modes -> karts
  36. tracks -> graphics
  37. karts -> graphics
  38. tracks -> items
  39. graphics -> irrlicht
  40. guiengine -> irrlicht
  41. states_screens -> guiengine
  42. states_screens -> input
  43. guiengine -> input
  44. karts->physics
  45. tracks->physics
  46. karts -> controller
  47. input->controller
  48. tracks -> animations
  49. physics -> animations
  50. }
  51. \enddot
  52. Note that this graph is only an approximation because the real one would be
  53. much too complicated :)
  54. \section Modules
  55. \li \ref addonsgroup :
  56. Handles add-ons that can be downloaded.
  57. \li \ref animations :
  58. This module manages interpolation-based animation (of position, rotation
  59. and/or scale)
  60. \li \ref audio :
  61. This module handles audio (sound effects and music).
  62. \li \ref challenges :
  63. This module handles the challenge system, which locks features (tracks, karts
  64. modes, etc.) until the user completes some task.
  65. \li \ref config :
  66. This module handles the user configuration, the supertuxkart configuration
  67. file (which contains options usually not edited by the player) and the input
  68. configuration file.
  69. \li \ref graphics :
  70. This module contains the core graphics engine, that is mostly a thin layer
  71. on top of irrlicht providing some additional features we need for STK
  72. (like particles, more scene node types, mesh manipulation tools, material
  73. management, etc...)
  74. \li \ref guiengine :
  75. Contains the generic GUI engine (contains the widgets and the backing logic
  76. for event handling, the skin, screens and dialogs). See module @ref states_screens
  77. for the actual STK GUI screens. Note that all input comes through this module
  78. too.
  79. \li \ref widgetsgroup :
  80. Contains the various types of widgets supported by the GUI engine.
  81. \li \ref input :
  82. Contains classes for input management (keyboard and gamepad)
  83. \li \ref io :
  84. Contains generic utility classes for file I/O (especially XML handling).
  85. \li \ref items :
  86. Defines the various collectibles and weapons of STK.
  87. \li \ref karts :
  88. Contains classes that deal with the properties, models and physics
  89. of karts.
  90. \li \ref controller :
  91. Contains kart controllers, which are either human players or AIs
  92. (this module thus contains the AIs)
  93. \li \ref modes :
  94. Contains the logic for the various game modes (race, follow the leader,
  95. battle, etc.)
  96. \li \ref physics :
  97. Contains various physics utilities.
  98. \li \ref race :
  99. Contains the race information that is conceptually above what you can find
  100. in group Modes. Handles highscores, grands prix, number of karts, which
  101. track was selected, etc.
  102. \li \ref states_screens :
  103. Contains the various screens and dialogs of the STK user interface,
  104. using the facilities of the guiengine module. Also contains the
  105. stack of menus and handles state management (in-game vs menu).
  106. \li \ref tracks :
  107. Contains information about tracks, namely drivelines, checklines and track
  108. objects.
  109. \li \ref tutorial :
  110. Work in progress
  111. */
  112. #ifdef WIN32
  113. # ifdef __CYGWIN__
  114. # include <unistd.h>
  115. # endif
  116. # define _WINSOCKAPI_
  117. # include <windows.h>
  118. # ifdef _MSC_VER
  119. # include <direct.h>
  120. # endif
  121. #else
  122. # include <unistd.h>
  123. #endif
  124. #include <stdexcept>
  125. #include <cstdio>
  126. #include <string>
  127. #include <cstring>
  128. #include <sstream>
  129. #include <algorithm>
  130. #include <IEventReceiver.h>
  131. #include "main_loop.hpp"
  132. #include "addons/addons_manager.hpp"
  133. #include "addons/inetwork_http.hpp"
  134. #include "addons/news_manager.hpp"
  135. #include "audio/music_manager.hpp"
  136. #include "audio/sfx_manager.hpp"
  137. #include "challenges/unlock_manager.hpp"
  138. #include "config/stk_config.hpp"
  139. #include "config/user_config.hpp"
  140. #include "config/player.hpp"
  141. #include "graphics/hardware_skinning.hpp"
  142. #include "graphics/irr_driver.hpp"
  143. #include "graphics/material_manager.hpp"
  144. #include "graphics/particle_kind_manager.hpp"
  145. #include "graphics/referee.hpp"
  146. #include "graphics/view_player.hpp"
  147. #include "guiengine/engine.hpp"
  148. #include "guiengine/event_handler.hpp"
  149. #include "input/input_manager.hpp"
  150. #include "input/device_manager.hpp"
  151. #include "input/wiimote_manager.hpp"
  152. #include "io/file_manager.hpp"
  153. #include "items/attachment_manager.hpp"
  154. #include "items/item_manager.hpp"
  155. #include "items/projectile_manager.hpp"
  156. #include "karts/controller/ai_base_controller.hpp"
  157. #include "karts/kart_properties.hpp"
  158. #include "karts/kart_properties_manager.hpp"
  159. #include "modes/demo_world.hpp"
  160. #include "modes/profile_world.hpp"
  161. #include "network/network_manager.hpp"
  162. #include "race/grand_prix_manager.hpp"
  163. #include "race/highscore_manager.hpp"
  164. #include "race/history.hpp"
  165. #include "race/race_manager.hpp"
  166. #include "replay/replay_play.hpp"
  167. #include "replay/replay_recorder.hpp"
  168. #include "states_screens/story_mode_lobby.hpp"
  169. #include "states_screens/state_manager.hpp"
  170. #include "states_screens/dialogs/message_dialog.hpp"
  171. #include "tracks/track.hpp"
  172. #include "tracks/track_manager.hpp"
  173. #include "utils/constants.hpp"
  174. #include "utils/leak_check.hpp"
  175. #include "utils/log.hpp"
  176. #include "utils/translation.hpp"
  177. static void cleanSuperTuxKart();
  178. // ============================================================================
  179. // gamepad visualisation screen
  180. // ============================================================================
  181. void gamepadVisualisation()
  182. {
  183. core::array<SJoystickInfo> irrlicht_gamepads;
  184. irr_driver->getDevice()->activateJoysticks(irrlicht_gamepads);
  185. struct Gamepad
  186. {
  187. s16 m_axis[SEvent::SJoystickEvent::NUMBER_OF_AXES];
  188. bool m_button_state[SEvent::SJoystickEvent::NUMBER_OF_BUTTONS];
  189. };
  190. #define GAMEPAD_COUNT 8 // const won't work
  191. class EventReceiver : public IEventReceiver
  192. {
  193. public:
  194. Gamepad m_gamepads[GAMEPAD_COUNT];
  195. EventReceiver()
  196. {
  197. for (int n=0; n<GAMEPAD_COUNT; n++)
  198. {
  199. Gamepad& g = m_gamepads[n];
  200. for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_AXES; i++)
  201. g.m_axis[i] = 0;
  202. for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_BUTTONS; i++)
  203. g.m_button_state[i] = false;
  204. }
  205. }
  206. virtual bool OnEvent (const irr::SEvent &event)
  207. {
  208. switch (event.EventType)
  209. {
  210. case EET_JOYSTICK_INPUT_EVENT :
  211. {
  212. const SEvent::SJoystickEvent& evt = event.JoystickEvent;
  213. if (evt.Joystick >= GAMEPAD_COUNT) return true;
  214. Gamepad& g = m_gamepads[evt.Joystick];
  215. for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_AXES;i++)
  216. {
  217. g.m_axis[i] = evt.Axis[i];
  218. }
  219. for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_BUTTONS;
  220. i++)
  221. {
  222. g.m_button_state[i] = evt.IsButtonPressed(i);
  223. }
  224. break;
  225. }
  226. case EET_KEY_INPUT_EVENT:
  227. {
  228. const SEvent::SKeyInput& evt = event.KeyInput;
  229. if (evt.PressedDown)
  230. {
  231. if (evt.Key == KEY_RETURN || evt.Key == KEY_ESCAPE ||
  232. evt.Key == KEY_SPACE)
  233. {
  234. exit(0);
  235. }
  236. }
  237. }
  238. default:
  239. // don't care about others
  240. break;
  241. }
  242. return true;
  243. }
  244. };
  245. EventReceiver* events = new EventReceiver();
  246. irr_driver->getDevice()->setEventReceiver(events);
  247. while (true)
  248. {
  249. if (!irr_driver->getDevice()->run()) break;
  250. video::IVideoDriver* driver = irr_driver->getVideoDriver();
  251. const core::dimension2du size = driver ->getCurrentRenderTargetSize();
  252. driver->beginScene(true, true, video::SColor(255,0,0,0));
  253. for (int n=0; n<GAMEPAD_COUNT; n++)
  254. {
  255. Gamepad& g = events->m_gamepads[n];
  256. const int MARGIN = 10;
  257. const int x = (n & 1 ? size.Width/2 + MARGIN : MARGIN );
  258. const int w = size.Width/2 - MARGIN*2;
  259. const int h = size.Height/(GAMEPAD_COUNT/2) - MARGIN*2;
  260. const int y = size.Height/(GAMEPAD_COUNT/2)*(n/2) + MARGIN;
  261. driver->draw2DRectangleOutline( core::recti(x, y, x+w, y+h) );
  262. const int btn_y = y + 5;
  263. const int btn_x = x + 5;
  264. const int BTN_SIZE =
  265. (w - 10)/SEvent::SJoystickEvent::NUMBER_OF_BUTTONS;
  266. for (int b=0; b<SEvent::SJoystickEvent::NUMBER_OF_BUTTONS; b++)
  267. {
  268. core::position2di pos(btn_x + b*BTN_SIZE, btn_y);
  269. core::dimension2di size(BTN_SIZE, BTN_SIZE);
  270. if (g.m_button_state[b])
  271. {
  272. driver->draw2DRectangle (video::SColor(255,255,0,0),
  273. core::recti(pos, size));
  274. }
  275. driver->draw2DRectangleOutline( core::recti(pos, size) );
  276. }
  277. const int axis_y = btn_y + BTN_SIZE + 5;
  278. const int axis_x = btn_x;
  279. const int axis_w = w - 10;
  280. const int axis_h = (h - BTN_SIZE - 15)
  281. / SEvent::SJoystickEvent::NUMBER_OF_AXES;
  282. for (int a=0; a<SEvent::SJoystickEvent::NUMBER_OF_AXES; a++)
  283. {
  284. const float rate = g.m_axis[a] / 32767.0f;
  285. core::position2di pos(axis_x, axis_y + a*axis_h);
  286. core::dimension2di size(axis_w, axis_h);
  287. const bool deadzone = (abs(g.m_axis[a]) < DEADZONE_JOYSTICK);
  288. core::recti fillbar(core::position2di(axis_x + axis_w/2,
  289. axis_y + a*axis_h),
  290. core::dimension2di( (int)(axis_w/2*rate),
  291. axis_h) );
  292. fillbar.repair(); // dimension may be negative
  293. driver->draw2DRectangle (deadzone ? video::SColor(255,255,0,0)
  294. : video::SColor(255,0,255,0),
  295. fillbar);
  296. driver->draw2DRectangleOutline( core::recti(pos, size) );
  297. }
  298. }
  299. driver->endScene();
  300. }
  301. } // gamepadVisualisation
  302. // ============================================================================
  303. /** Sets the Christmas flag (m_xmas_enabled), depending on currently set
  304. * Christ mode (m_xmas_mode)
  305. */
  306. void handleXmasMode()
  307. {
  308. bool xmas = false;
  309. switch(UserConfigParams::m_xmas_mode)
  310. {
  311. case 0:
  312. {
  313. int day, month;
  314. StkTime::getDate(&day, &month);
  315. // Christmat hats are shown between 17. of December
  316. // and 5th of January
  317. xmas = (month == 12 && day>=17) || (month == 1 && day <=5);
  318. break;
  319. }
  320. case 1: xmas = true; break;
  321. default: xmas = false; break;
  322. } // switch m_xmas_mode
  323. if(xmas)
  324. kart_properties_manager->setHatMeshName("christmas_hat.b3d");
  325. } // handleXmasMode
  326. // ----------------------------------------------------------------------------
  327. /** Prints help for command line options to stdout.
  328. */
  329. void cmdLineHelp(char* invocation)
  330. {
  331. Log::info("main",
  332. "Usage: %s [OPTIONS]\n\n"
  333. "Run SuperTuxKart, a racing game with go-kart that features"
  334. " the Tux and friends.\n\n"
  335. "Options:\n"
  336. " -N, --no-start-screen Immediately start race without showing a "
  337. "menu.\n"
  338. " -R, --race-now Same as -N but also skip the ready-set-go phase"
  339. " and the music.\n"
  340. " -t, --track NAME Start at track NAME (see --list-tracks).\n"
  341. " --gp NAME Start the specified Grand Prix.\n"
  342. " --stk-config FILE use ./data/FILE instead of "
  343. "./data/stk_config.xml\n"
  344. " -l, --list-tracks Show available tracks.\n"
  345. " -k, --numkarts NUM Number of karts on the racetrack.\n"
  346. " --kart NAME Use kart number NAME (see --list-karts).\n"
  347. " --ai=a,b,... Use the karts a, b, ... for the AI.\n"
  348. " --list-karts Show available karts.\n"
  349. " --laps N Define number of laps to N.\n"
  350. " --mode N N=1 novice, N=2 driver, N=3 racer.\n"
  351. " --type N N=0 Normal, N=1 Time trial, N=2 FTL\n"
  352. " --reverse Play track in reverse (if allowed)\n"
  353. // TODO: add back "--players" switch
  354. // " --players n Define number of players to between 1 and 4.\n"
  355. " -f, --fullscreen Select fullscreen display.\n"
  356. " -w, --windowed Windowed display (default).\n"
  357. " -s, --screensize WxH Set the screen size (e.g. 320x200).\n"
  358. " -v, --version Show version of SuperTuxKart.\n"
  359. " --trackdir DIR A directory from which additional tracks are "
  360. "loaded.\n"
  361. " --animations=n Play karts' animations (All: 2, Humans only: 1,"
  362. " Nobody: 0).\n"
  363. " --gfx=n Play other graphical effects like impact stars "
  364. "dance,\n"
  365. " water animations or explosions (Enable: 1, "
  366. "Disable: 0).\n"
  367. " --weather=n Show weather effects like rain or snow (0 or 1 "
  368. "as --gfx).\n"
  369. " --camera-style=n Flexible (0) or hard like v0.6 (1) kart-camera "
  370. "link.\n"
  371. " --profile-laps=n Enable automatic driven profile mode for n "
  372. "laps.\n"
  373. " --profile-time=n Enable automatic driven profile mode for n "
  374. "seconds.\n"
  375. " --no-graphics Do not display the actual race.\n"
  376. " --demo-mode t Enables demo mode after t seconds idle time in "
  377. "main menu.\n"
  378. " --demo-tracks t1,t2 List of tracks to be used in demo mode. No\n"
  379. " spaces are allowed in the track names.\n"
  380. " --demo-laps n Number of laps in a demo.\n"
  381. " --demo-karts n Number of karts to use in a demo.\n"
  382. " --demo-startrace Skip the ready-set-go phase (everywhere).\n"
  383. " --ghost Replay ghost data together with one player kart.\n"
  384. " --nbviews n Number of views of the display (PAF).\n"
  385. " --shader Will render via shader (soft by default).\n"
  386. " --angle n Distance between two camera (soft rendering).\n"
  387. // " --history Replay history file 'history.dat'.\n"
  388. // " --history=n Replay history file 'history.dat' using:\n"
  389. // " n=1: recorded positions\n"
  390. // " n=2: recorded key strokes\n"
  391. //" --server[=port] This is the server (running on the specified "
  392. // "port).\n"
  393. //" --client=ip This is a client, connect to the specified ip"
  394. // " address.\n"
  395. //" --port=n Port number to use.\n"
  396. //" --numclients=n Number of clients to wait for (server "
  397. // "only).\n"
  398. " --no-console Does not write messages in the console but to\n"
  399. " stdout.log.\n"
  400. " --console Write messages in the console and files\n"
  401. " -h, --help Show this help.\n"
  402. "\n"
  403. "You can visit SuperTuxKart's homepage at "
  404. "http://supertuxkart.sourceforge.net\n\n", invocation
  405. );
  406. } // cmdLineHelp
  407. //=============================================================================
  408. /** For base options that don't need much to be inited (and, in some cases,
  409. * that need to be read before initing stuff) - it only assumes that
  410. * user config is loaded (necessary to check for blacklisted screen
  411. * resolutions), but nothing else (esp. not kart_properties_manager and
  412. * track_manager, since their search path might be extended by command
  413. * line options).
  414. */
  415. int handleCmdLinePreliminary(int argc, char **argv)
  416. {
  417. int n;
  418. for(int i=1; i<argc; i++)
  419. {
  420. if(argv[i][0] != '-') continue;
  421. if (!strcmp(argv[i], "--help" ) ||
  422. !strcmp(argv[i], "-help" ) ||
  423. !strcmp(argv[i], "-h" ) )
  424. {
  425. cmdLineHelp(argv[0]);
  426. exit(0);
  427. }
  428. else if(!strcmp(argv[i], "--gamepad-visualisation") ||
  429. !strcmp(argv[i], "--gamepad-visualization") )
  430. {
  431. UserConfigParams::m_gamepad_visualisation=true;
  432. }
  433. else if ( !strcmp(argv[i], "--debug=memory") )
  434. {
  435. UserConfigParams::m_verbosity |= UserConfigParams::LOG_MEMORY;
  436. }
  437. else if ( !strcmp(argv[i], "--debug=addons") )
  438. {
  439. UserConfigParams::m_verbosity |= UserConfigParams::LOG_ADDONS;
  440. }
  441. else if ( !strcmp(argv[i], "--debug=gui") )
  442. {
  443. UserConfigParams::m_verbosity |= UserConfigParams::LOG_GUI;
  444. }
  445. else if ( !strcmp(argv[i], "--debug=flyable") )
  446. {
  447. UserConfigParams::m_verbosity |= UserConfigParams::LOG_FLYABLE;
  448. }
  449. else if ( !strcmp(argv[i], "--debug=misc") )
  450. {
  451. UserConfigParams::m_verbosity |= UserConfigParams::LOG_MISC;
  452. }
  453. else if ( sscanf(argv[i], "--xmas=%d", &n) )
  454. {
  455. UserConfigParams::m_xmas_mode = n;
  456. }
  457. else if( !strcmp(argv[i], "--no-console"))
  458. {
  459. UserConfigParams::m_log_errors_to_console=false;
  460. }
  461. else if( !strcmp(argv[i], "--console"))
  462. {
  463. UserConfigParams::m_log_errors_to_console=true;
  464. }
  465. else if( !strcmp(argv[i], "--log=nocolor"))
  466. {
  467. Log::disableColor();
  468. Log::verbose("main", "Colours disabled.\n");
  469. }
  470. else if(sscanf(argv[i], "--log=%d",&n)==1)
  471. {
  472. Log::setLogLevel(n);
  473. }
  474. else if ( !strcmp(argv[i], "--debug=all") )
  475. {
  476. UserConfigParams::m_verbosity |= UserConfigParams::LOG_ALL;
  477. }
  478. else if( (!strcmp(argv[i], "--stk-config")) && i+1<argc )
  479. {
  480. stk_config->load(file_manager->getDataFile(argv[i+1]));
  481. Log::info("main", "STK config will be read from %s.\n",argv[i+1] );
  482. i++;
  483. }
  484. else if( !strcmp(argv[i], "--trackdir") && i+1<argc )
  485. {
  486. TrackManager::addTrackSearchDir(argv[i+1]);
  487. i++;
  488. }
  489. else if( !strcmp(argv[i], "--kartdir") && i+1<argc )
  490. {
  491. KartPropertiesManager::addKartSearchDir(argv[i+1]);
  492. i++;
  493. }
  494. else if( !strcmp(argv[i], "--nbviews") && i+1<argc)
  495. {
  496. int nb;
  497. StringUtils::fromString(argv[i+1], nb);
  498. UserConfigParams::m_nbviews = nb;
  499. i++;
  500. }
  501. else if( !strcmp(argv[i], "--angle") && i+1<argc)
  502. {
  503. float nb;
  504. StringUtils::fromString(argv[i+1], nb);
  505. UserConfigParams::m_interocularDistance = nb;
  506. i++;
  507. }
  508. else if( !strcmp(argv[i], "--no-graphics") || !strncmp(argv[i], "--list-", 7) ||
  509. !strcmp(argv[i], "-l" ))
  510. {
  511. ProfileWorld::disableGraphics();
  512. UserConfigParams::m_log_errors_to_console=true;
  513. }
  514. #if !defined(WIN32) && !defined(__CYGWIN)
  515. else if ( !strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f"))
  516. {
  517. // Check that current res is not blacklisted
  518. std::ostringstream o;
  519. o << UserConfigParams::m_width << "x"
  520. << UserConfigParams::m_height;
  521. std::string res = o.str();
  522. if (std::find(UserConfigParams::m_blacklist_res.begin(),
  523. UserConfigParams::m_blacklist_res.end(),res)
  524. == UserConfigParams::m_blacklist_res.end())
  525. UserConfigParams::m_fullscreen = true;
  526. else
  527. Log::warn("main", "Resolution %s has been blacklisted, so it "
  528. "is not available!\n", res.c_str());
  529. }
  530. else if ( !strcmp(argv[i], "--windowed") || !strcmp(argv[i], "-w"))
  531. {
  532. UserConfigParams::m_fullscreen = false;
  533. }
  534. #endif
  535. else if ( (!strcmp(argv[i], "--screensize") || !strcmp(argv[i], "-s") )
  536. && i+1<argc)
  537. {
  538. //Check if fullscreen and new res is blacklisted
  539. int width, height;
  540. if (sscanf(argv[i+1], "%dx%d", &width, &height) == 2)
  541. {
  542. std::ostringstream o;
  543. o << width << "x" << height;
  544. std::string res = o.str();
  545. if (!UserConfigParams::m_fullscreen ||
  546. std::find(UserConfigParams::m_blacklist_res.begin(),
  547. UserConfigParams::m_blacklist_res.end(),res) ==
  548. UserConfigParams::m_blacklist_res.end())
  549. {
  550. UserConfigParams::m_prev_width =
  551. UserConfigParams::m_width = width;
  552. UserConfigParams::m_prev_height =
  553. UserConfigParams::m_height = height;
  554. Log::verbose("main", "You choose to use %dx%d.\n",
  555. (int)UserConfigParams::m_width,
  556. (int)UserConfigParams::m_height );
  557. }
  558. else
  559. Log::warn("main", "Resolution %s has been blacklisted, so "
  560. "it is not available!\n", res.c_str());
  561. i++;
  562. }
  563. else
  564. {
  565. Log::fatal("main", "Error: --screensize argument must be "
  566. "given as WIDTHxHEIGHT");
  567. }
  568. }
  569. else if (strcmp(argv[i], "--version") == 0 ||
  570. strcmp(argv[i], "-v" ) == 0 )
  571. {
  572. Log::info("main", "==============================");
  573. Log::info("main", "SuperTuxKart, %s.", STK_VERSION ) ;
  574. #ifdef SVNVERSION
  575. Log::info("main", "SuperTuxKart, SVN revision number '%s'.",
  576. SVNVERSION ) ;
  577. #endif
  578. // IRRLICHT_VERSION_SVN
  579. Log::info("main", "Irrlicht version %i.%i.%i (%s)",
  580. IRRLICHT_VERSION_MAJOR , IRRLICHT_VERSION_MINOR,
  581. IRRLICHT_VERSION_REVISION, IRRLICHT_SDK_VERSION );
  582. Log::info("main", "==============================");
  583. } // --verbose or -v
  584. }
  585. return 0;
  586. } // handleCmdLinePreliminary
  587. // ============================================================================
  588. /** Handles command line options.
  589. * \param argc Number of command line options
  590. * \param argv Command line options.
  591. */
  592. int handleCmdLine(int argc, char **argv)
  593. {
  594. int n;
  595. char s[1024];
  596. for(int i=1; i<argc; i++)
  597. {
  598. if(!strcmp(argv[i], "--gamepad-debug"))
  599. {
  600. UserConfigParams::m_gamepad_debug=true;
  601. }
  602. else if (!strcmp(argv[i], "--wiimote-debug"))
  603. {
  604. UserConfigParams::m_wiimote_debug = true;
  605. }
  606. else if (!strcmp(argv[i], "--tutorial-debug"))
  607. {
  608. UserConfigParams::m_tutorial_debug = true;
  609. }
  610. else if(sscanf(argv[i], "--track-debug=%d",&n)==1)
  611. {
  612. UserConfigParams::m_track_debug=n;
  613. }
  614. else if(!strcmp(argv[i], "--track-debug"))
  615. {
  616. UserConfigParams::m_track_debug=1;
  617. }
  618. else if(!strcmp(argv[i], "--material-debug"))
  619. {
  620. UserConfigParams::m_material_debug = true;
  621. }
  622. else if(!strcmp(argv[i], "--ftl-debug"))
  623. {
  624. UserConfigParams::m_ftl_debug = true;
  625. }
  626. else if(UserConfigParams::m_artist_debug_mode &&
  627. !strcmp(argv[i], "--camera-wheel-debug"))
  628. {
  629. UserConfigParams::m_camera_debug=2;
  630. }
  631. else if(UserConfigParams::m_artist_debug_mode &&
  632. !strcmp(argv[i], "--camera-debug"))
  633. {
  634. UserConfigParams::m_camera_debug=1;
  635. }
  636. else if(UserConfigParams::m_artist_debug_mode &&
  637. !strcmp(argv[i], "--physics-debug"))
  638. {
  639. UserConfigParams::m_physics_debug=1;
  640. }
  641. else if(!strcmp(argv[i], "--kartsize-debug"))
  642. {
  643. for(unsigned int i=0;
  644. i<kart_properties_manager->getNumberOfKarts(); i++)
  645. {
  646. const KartProperties *km =
  647. kart_properties_manager->getKartById(i);
  648. Log::info("main", "%s:\t%swidth: %f length: %f height: %f "
  649. "mesh-buffer count %d",
  650. km->getIdent().c_str(),
  651. (km->getIdent().size()<7) ? "\t" : "",
  652. km->getMasterKartModel().getWidth(),
  653. km->getMasterKartModel().getLength(),
  654. km->getMasterKartModel().getHeight(),
  655. km->getMasterKartModel().getModel()
  656. ->getMeshBufferCount());
  657. }
  658. }
  659. else if(UserConfigParams::m_artist_debug_mode &&
  660. !strcmp(argv[i], "--check-debug"))
  661. {
  662. UserConfigParams::m_check_debug=true;
  663. }
  664. else if(!strcmp(argv[i], "--slipstream-debug"))
  665. {
  666. UserConfigParams::m_slipstream_debug=true;
  667. }
  668. else if(!strcmp(argv[i], "--rendering-debug"))
  669. {
  670. UserConfigParams::m_rendering_debug=true;
  671. }
  672. else if(!strcmp(argv[i], "--ai-debug"))
  673. {
  674. AIBaseController::enableDebug();
  675. }
  676. else if(sscanf(argv[i], "--server=%d",&n)==1)
  677. {
  678. network_manager->setMode(NetworkManager::NW_SERVER);
  679. UserConfigParams::m_server_port = n;
  680. }
  681. else if( !strcmp(argv[i], "--server") )
  682. {
  683. network_manager->setMode(NetworkManager::NW_SERVER);
  684. }
  685. else if( sscanf(argv[i], "--port=%d", &n) )
  686. {
  687. UserConfigParams::m_server_port=n;
  688. }
  689. else if( sscanf(argv[i], "--client=%1023s", s) )
  690. {
  691. network_manager->setMode(NetworkManager::NW_CLIENT);
  692. UserConfigParams::m_server_address=s;
  693. }
  694. else if ( sscanf(argv[i], "--gfx=%d", &n) )
  695. {
  696. if (n)
  697. {
  698. UserConfigParams::m_graphical_effects = true;
  699. }
  700. else
  701. {
  702. UserConfigParams::m_graphical_effects = false;
  703. }
  704. }
  705. else if ( sscanf(argv[i], "--weather=%d", &n) )
  706. {
  707. if (n)
  708. {
  709. UserConfigParams::m_weather_effects = true;
  710. }
  711. else
  712. {
  713. UserConfigParams::m_weather_effects = false;
  714. }
  715. }
  716. else if ( sscanf(argv[i], "--animations=%d", &n) )
  717. {
  718. UserConfigParams::m_show_steering_animations = n;
  719. }
  720. else if ( sscanf(argv[i], "--camera-style=%d", &n) )
  721. {
  722. UserConfigParams::m_camera_style = n;
  723. }
  724. else if( (!strcmp(argv[i], "--kart") && i+1<argc ))
  725. {
  726. unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0]
  727. .getUniqueID() );
  728. if (!unlock_manager->getCurrentSlot()->isLocked(argv[i+1]))
  729. {
  730. const KartProperties *prop =
  731. kart_properties_manager->getKart(argv[i+1]);
  732. if(prop)
  733. {
  734. UserConfigParams::m_default_kart = argv[i+1];
  735. // if a player was added with -N, change its kart.
  736. // Otherwise, nothing to do, kart choice will be picked
  737. // up upon player creation.
  738. if (StateManager::get()->activePlayerCount() > 0)
  739. {
  740. race_manager->setLocalKartInfo(0, argv[i+1]);
  741. }
  742. Log::verbose("main", "You chose to use kart '%s'.",
  743. argv[i+1] ) ;
  744. i++;
  745. }
  746. else
  747. {
  748. Log::warn("main", "Kart '%s' not found, ignored.",
  749. argv[i+1]);
  750. i++; // ignore the next parameter, otherwise STK will abort
  751. }
  752. }
  753. else // kart locked
  754. {
  755. Log::warn("main", "Kart '%s' has not been unlocked yet.",
  756. argv[i+1]);
  757. Log::warn("main",
  758. "Use --list-karts to list available karts.");
  759. return 0;
  760. } // if kart locked
  761. }
  762. else if( sscanf(argv[i], "--ai=%1023s", s)==1)
  763. {
  764. const std::vector<std::string> l=
  765. StringUtils::split(std::string(s),',');
  766. race_manager->setDefaultAIKartList(l);
  767. // Add 1 for the player kart
  768. race_manager->setNumKarts(l.size()+1);
  769. }
  770. else if( (!strcmp(argv[i], "--mode") && i+1<argc ))
  771. {
  772. int n = atoi(argv[i+1]);
  773. if(n<0 || n>RaceManager::DIFFICULTY_LAST)
  774. Log::warn("main", "Invalid difficulty '%s' - ignored.\n",
  775. argv[i+1]);
  776. else
  777. race_manager->setDifficulty(RaceManager::Difficulty(n));
  778. i++;
  779. }
  780. else if( (!strcmp(argv[i], "--type") && i+1<argc ))
  781. {
  782. switch (atoi(argv[i+1]))
  783. {
  784. case 0: race_manager
  785. ->setMinorMode(RaceManager::MINOR_MODE_NORMAL_RACE);
  786. break;
  787. case 1: race_manager
  788. ->setMinorMode(RaceManager::MINOR_MODE_TIME_TRIAL);
  789. break;
  790. case 2: race_manager
  791. ->setMinorMode(RaceManager::MINOR_MODE_FOLLOW_LEADER);
  792. break;
  793. default:
  794. Log::warn("main", "Invalid race type '%d' - ignored.",
  795. atoi(argv[i+1]));
  796. }
  797. i++;
  798. }
  799. else if( !strcmp(argv[i], "--reverse"))
  800. {
  801. race_manager->setReverseTrack(true);
  802. }
  803. else if( (!strcmp(argv[i], "--track") || !strcmp(argv[i], "-t"))
  804. && i+1<argc )
  805. {
  806. unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0]
  807. .getUniqueID() );
  808. if (!unlock_manager->getCurrentSlot()->isLocked(argv[i+1]))
  809. {
  810. race_manager->setTrack(argv[i+1]);
  811. Log::verbose("main", "You choose to start in track '%s'.",
  812. argv[i+1] );
  813. Track* t = track_manager->getTrack(argv[i+1]);
  814. if (t == NULL)
  815. {
  816. Log::warn("main", "Can't find track named '%s'.",
  817. argv[i+1]);
  818. }
  819. else if (t->isArena())
  820. {
  821. //if it's arena, don't create ai karts
  822. const std::vector<std::string> l;
  823. race_manager->setDefaultAIKartList(l);
  824. // Add 1 for the player kart
  825. race_manager->setNumKarts(1);
  826. race_manager->setMinorMode(RaceManager::MINOR_MODE_3_STRIKES);
  827. }
  828. else if(t->isSoccer())
  829. {
  830. //if it's soccer, don't create ai karts
  831. const std::vector<std::string> l;
  832. race_manager->setDefaultAIKartList(l);
  833. // Add 1 for the player kart
  834. race_manager->setNumKarts(1);
  835. race_manager->setMinorMode(RaceManager::MINOR_MODE_SOCCER);
  836. }
  837. }
  838. else
  839. {
  840. Log::warn("main", "Track '%s' has not been unlocked yet.",
  841. argv[i+1]);
  842. Log::warn("main", "Use --list-tracks to list available "
  843. "tracks.");
  844. return 0;
  845. }
  846. i++;
  847. }
  848. else if( (!strcmp(argv[i], "--gp")) && i+1<argc)
  849. {
  850. race_manager->setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX);
  851. const GrandPrixData *gp =
  852. grand_prix_manager->getGrandPrix(argv[i+1]);
  853. if (gp == NULL)
  854. {
  855. Log::warn("main", "There is no GP named '%s'.", argv[i+1]);
  856. return 0;
  857. }
  858. race_manager->setGrandPrix(*gp);
  859. i++;
  860. }
  861. else if( (!strcmp(argv[i], "--numkarts") || !strcmp(argv[i], "-k")) &&
  862. i+1<argc )
  863. {
  864. UserConfigParams::m_num_karts = atoi(argv[i+1]);
  865. if(UserConfigParams::m_num_karts > stk_config->m_max_karts)
  866. {
  867. Log::warn("main",
  868. "Number of karts reset to maximum number %d.",
  869. stk_config->m_max_karts);
  870. UserConfigParams::m_num_karts = stk_config->m_max_karts;
  871. }
  872. race_manager->setNumKarts( UserConfigParams::m_num_karts );
  873. Log::verbose("main", "%d karts will be used.",
  874. (int)UserConfigParams::m_num_karts);
  875. i++;
  876. }
  877. else if( !strcmp(argv[i], "--list-tracks") || !strcmp(argv[i], "-l") )
  878. {
  879. Log::info("main", " Available tracks:" );
  880. unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0]
  881. .getUniqueID() );
  882. for (size_t i = 0; i != track_manager->getNumberOfTracks(); i++)
  883. {
  884. const Track *track = track_manager->getTrack(i);
  885. const char * locked = "";
  886. if ( unlock_manager->getCurrentSlot()
  887. ->isLocked(track->getIdent()) )
  888. {
  889. locked = " (locked)";
  890. }
  891. Log::info("main", "%-18s: %ls %s",
  892. track->getIdent().c_str(),
  893. track->getName(), locked);
  894. //}
  895. }
  896. Log::info("main", "Use --track N to choose track.");
  897. exit(0);
  898. }
  899. else if( !strcmp(argv[i], "--list-karts") )
  900. {
  901. Log::info("main", " Available karts:");
  902. for (unsigned int i = 0;
  903. i < kart_properties_manager->getNumberOfKarts(); i++)
  904. {
  905. const KartProperties* KP =
  906. kart_properties_manager->getKartById(i);
  907. unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0]
  908. .getUniqueID() );
  909. const char * locked = "";
  910. if (unlock_manager->getCurrentSlot()->isLocked(KP->getIdent()))
  911. locked = "(locked)";
  912. Log::info("main", " %-10s: %ls %s", KP->getIdent().c_str(),
  913. KP->getName(), locked);
  914. }
  915. exit(0);
  916. }
  917. else if ( !strcmp(argv[i], "--no-start-screen")
  918. || !strcmp(argv[i], "-N") )
  919. {
  920. UserConfigParams::m_no_start_screen = true;
  921. }
  922. else if ( !strcmp(argv[i], "--race-now")
  923. || !strcmp(argv[i], "-R") )
  924. {
  925. UserConfigParams::m_no_start_screen = true;
  926. UserConfigParams::m_race_now = true;
  927. }
  928. else if ( !strcmp(argv[i], "--laps") && i+1<argc )
  929. {
  930. int laps = atoi(argv[i+1]);
  931. if (laps < 0)
  932. {
  933. Log::error("main", "Invalid number of laps: %s.\n", argv[i+1] );
  934. return 0;
  935. }
  936. else
  937. {
  938. Log::verbose("main", "You choose to have %d laps.", laps);
  939. race_manager->setNumLaps(laps);
  940. i++;
  941. }
  942. }
  943. else if( sscanf(argv[i], "--profile-laps=%d", &n)==1)
  944. {
  945. if (n < 0)
  946. {
  947. Log::error("main", "Invalid number of profile-laps: %i.\n", n );
  948. return 0;
  949. }
  950. else
  951. {
  952. Log::verbose("main", "Profiling %d laps.",n);
  953. UserConfigParams::m_no_start_screen = true;
  954. ProfileWorld::setProfileModeLaps(n);
  955. race_manager->setNumLaps(n);
  956. }
  957. }
  958. else if( sscanf(argv[i], "--profile-time=%d", &n)==1)
  959. {
  960. Log::verbose("main", "Profiling: %d seconds.", n);
  961. UserConfigParams::m_no_start_screen = true;
  962. ProfileWorld::setProfileModeTime((float)n);
  963. race_manager->setNumLaps(999999); // profile end depends on time
  964. }
  965. else if( !strcmp(argv[i], "--no-graphics") )
  966. {
  967. // Set default profile mode of 1 lap if we haven't already set one
  968. if (!ProfileWorld::isProfileMode()) {
  969. UserConfigParams::m_no_start_screen = true;
  970. ProfileWorld::setProfileModeLaps(1);
  971. race_manager->setNumLaps(1);
  972. }
  973. }
  974. else if( !strcmp(argv[i], "--ghost"))
  975. {
  976. ReplayPlay::create();
  977. }
  978. else if( sscanf(argv[i], "--history=%d", &n)==1)
  979. {
  980. history->doReplayHistory( (History::HistoryReplayMode)n);
  981. // Force the no-start screen flag, since this initialises
  982. // the player structures correctly.
  983. UserConfigParams::m_no_start_screen = true;
  984. }
  985. else if( !strcmp(argv[i], "--history") )
  986. {
  987. history->doReplayHistory(History::HISTORY_POSITION);
  988. // Force the no-start screen flag, since this initialises
  989. // the player structures correctly.
  990. UserConfigParams::m_no_start_screen = true;
  991. }
  992. else if( !strcmp(argv[i], "--demo-mode") && i+1<argc)
  993. {
  994. unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0]
  995. .getUniqueID() );
  996. float t;
  997. StringUtils::fromString(argv[i+1], t);
  998. DemoWorld::enableDemoMode(t);
  999. // The default number of laps is taken from ProfileWorld and
  1000. // is 0. So set a more useful default for demo mode.
  1001. DemoWorld::setNumLaps(2);
  1002. i++;
  1003. }
  1004. else if( !strcmp(argv[i], "--demo-laps") && i+1<argc)
  1005. {
  1006. // Note that we use a separate setting for demo mode to avoid the
  1007. // problem that someone plays a game, and in further demos then
  1008. // the wrong (i.e. last selected) number of laps would be used
  1009. DemoWorld::setNumLaps(atoi(argv[i+1]));
  1010. i++;
  1011. }
  1012. else if( !strcmp(argv[i], "--demo-karts") && i+1<argc)
  1013. {
  1014. // Note that we use a separate setting for demo mode to avoid the
  1015. // problem that someone plays a game, and in further demos then
  1016. // the wrong (i.e. last selected) number of karts would be used
  1017. DemoWorld::setNumKarts(atoi(argv[i+1]));
  1018. i++;
  1019. }
  1020. else if( !strcmp(argv[i], "--demo-tracks") && i+1<argc)
  1021. {
  1022. DemoWorld::setTracks(StringUtils::split(std::string(argv[i+1]),
  1023. ','));
  1024. i++;
  1025. }
  1026. else if ( !strcmp(argv[i], "--demo-startrace") )
  1027. {
  1028. UserConfigParams::m_race_now = true;
  1029. }
  1030. else if( !strcmp(argv[i], "--shader"))
  1031. {
  1032. ViewPlayer::switchSVAlg();
  1033. }
  1034. #ifdef ENABLE_WIIUSE
  1035. else if( !strcmp(argv[i], "--wii"))
  1036. {
  1037. WiimoteManager::enable();
  1038. }
  1039. #endif
  1040. // these commands are already processed in handleCmdLinePreliminary,
  1041. // but repeat this just so that we don't get error messages about
  1042. // unknown commands
  1043. else if( !strcmp(argv[i], "--stk-config")&& i+1<argc ) { i++; }
  1044. else if( !strcmp(argv[i], "--trackdir") && i+1<argc ) { i++; }
  1045. else if( !strcmp(argv[i], "--kartdir") && i+1<argc ) { i++; }
  1046. else if( !strcmp(argv[i], "--debug=memory" ) ) {}
  1047. else if( !strcmp(argv[i], "--debug=addons" ) ) {}
  1048. else if( !strcmp(argv[i], "--debug=gui" ) ) {}
  1049. else if( !strcmp(argv[i], "--debug=flyable") ) {}
  1050. else if( !strcmp(argv[i], "--debug=misc" ) ) {}
  1051. else if( !strcmp(argv[i], "--debug=all" ) ) {}
  1052. else if ( sscanf(argv[i], "--xmas=%d", &n) ) {}
  1053. else if( !strcmp(argv[i], "--log=nocolor" ) ) {}
  1054. else if( sscanf(argv[i], "--log=%d",&n )==1 ) {}
  1055. else if( !strcmp(argv[i], "--no-console" ) ) {}
  1056. else if( !strcmp(argv[i], "--console" ) ) {}
  1057. else if( !strcmp(argv[i], "--screensize") ||
  1058. !strcmp(argv[i], "-s") ) {i++;}
  1059. else if( !strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f")) {}
  1060. else if( !strcmp(argv[i], "--windowed") || !strcmp(argv[i], "-w")) {}
  1061. else if( !strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")) {}
  1062. else if( !strcmp(argv[i], "--nbviews") && i+1<argc) { i++; }
  1063. else if( !strcmp(argv[i], "--angle") && i+1<argc) { i++; }
  1064. #ifdef __APPLE__
  1065. // on OS X, sometimes the Finder will pass a -psn* something parameter
  1066. // to the application
  1067. else if( strncmp(argv[i], "-psn", 3) == 0) {}
  1068. #endif
  1069. else
  1070. {
  1071. // invalid param needs to go to console
  1072. UserConfigParams::m_log_errors_to_console = true;
  1073. Log::error("main", "Invalid parameter: %s.\n", argv[i] );
  1074. cmdLineHelp(argv[0]);
  1075. cleanSuperTuxKart();
  1076. return 0;
  1077. }
  1078. } // for i <argc
  1079. if(UserConfigParams::m_no_start_screen)
  1080. unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0]
  1081. .getUniqueID() );
  1082. if(ProfileWorld::isProfileMode())
  1083. {
  1084. UserConfigParams::m_sfx = false; // Disable sound effects
  1085. UserConfigParams::m_music = false;// and music when profiling
  1086. }
  1087. return 1;
  1088. } // handleCmdLine
  1089. //=============================================================================
  1090. /** Initialises the minimum number of managers to get access to user_config.
  1091. */
  1092. void initUserConfig(char *argv[])
  1093. {
  1094. irr_driver = new IrrDriver();
  1095. file_manager = new FileManager(argv);
  1096. user_config = new UserConfig(); // needs file_manager
  1097. const bool config_ok = user_config->loadConfig();
  1098. if (UserConfigParams::m_language.toString() != "system")
  1099. {
  1100. #ifdef WIN32
  1101. std::string s=std::string("LANGUAGE=")
  1102. +UserConfigParams::m_language.c_str();
  1103. _putenv(s.c_str());
  1104. #else
  1105. setenv("LANGUAGE", UserConfigParams::m_language.c_str(), 1);
  1106. #endif
  1107. }
  1108. translations = new Translations(); // needs file_manager
  1109. stk_config = new STKConfig(); // in case of --stk-config
  1110. // command line parameters
  1111. user_config->postLoadInit();
  1112. if (!config_ok || UserConfigParams::m_all_players.size() == 0)
  1113. {
  1114. user_config->addDefaultPlayer();
  1115. user_config->saveConfig();
  1116. }
  1117. } // initUserConfig
  1118. //=============================================================================
  1119. void initRest()
  1120. {
  1121. stk_config->load(file_manager->getDataFile("stk_config.xml"));
  1122. // Now create the actual non-null device in the irrlicht driver
  1123. irr_driver->initDevice();
  1124. // Init GUI
  1125. IrrlichtDevice* device = irr_driver->getDevice();
  1126. video::IVideoDriver* driver = device->getVideoDriver();
  1127. if (UserConfigParams::m_gamepad_visualisation)
  1128. {
  1129. gamepadVisualisation();
  1130. exit(0);
  1131. }
  1132. GUIEngine::init(device, driver, StateManager::get());
  1133. // This only initialises the non-network part of the addons manager. The
  1134. // online section of the addons manager will be initialised from a
  1135. // separate thread running in network http.
  1136. news_manager = new NewsManager();
  1137. addons_manager = new AddonsManager();
  1138. INetworkHttp::create();
  1139. // Note that the network thread must be started after the assignment
  1140. // to network_http (since the thread might use network_http, otherwise
  1141. // a race condition can be introduced resulting in a crash).
  1142. INetworkHttp::get()->startNetworkThread();
  1143. music_manager = new MusicManager();
  1144. sfx_manager = new SFXManager();
  1145. // The order here can be important, e.g. KartPropertiesManager needs
  1146. // defaultKartProperties, which are defined in stk_config.
  1147. history = new History ();
  1148. ReplayRecorder::create();
  1149. material_manager = new MaterialManager ();
  1150. track_manager = new TrackManager ();
  1151. kart_properties_manager = new KartPropertiesManager();
  1152. projectile_manager = new ProjectileManager ();
  1153. powerup_manager = new PowerupManager ();
  1154. attachment_manager = new AttachmentManager ();
  1155. highscore_manager = new HighscoreManager ();
  1156. network_manager = new NetworkManager ();
  1157. KartPropertiesManager::addKartSearchDir(
  1158. file_manager->getAddonsFile("karts/"));
  1159. track_manager->addTrackSearchDir(
  1160. file_manager->getAddonsFile("tracks/"));
  1161. track_manager->loadTrackList();
  1162. music_manager->addMusicToTracks();
  1163. GUIEngine::addLoadingIcon(
  1164. irr_driver->getTexture(file_manager->getTextureFile("notes.png")) );
  1165. grand_prix_manager = new GrandPrixManager ();
  1166. // Consistency check for challenges, and enable all challenges
  1167. // that have all prerequisites fulfilled
  1168. grand_prix_manager->checkConsistency();
  1169. std::string file = file_manager->getTextureFile("cup_gold.png");
  1170. if(file.size()==0)
  1171. Log::fatal("main", "Can not find cup_gold.png, aborting.");
  1172. GUIEngine::addLoadingIcon( irr_driver->getTexture(file) );
  1173. race_manager = new RaceManager ();
  1174. // default settings for Quickstart
  1175. race_manager->setNumLocalPlayers(1);
  1176. race_manager->setNumLaps (3);
  1177. race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
  1178. race_manager->setMinorMode (RaceManager::MINOR_MODE_NORMAL_RACE);
  1179. race_manager->setDifficulty(
  1180. (RaceManager::Difficulty)(int)UserConfigParams::m_difficulty);
  1181. } // initRest
  1182. //=============================================================================
  1183. /** Frees all manager and their associated memory.
  1184. */
  1185. static void cleanSuperTuxKart()
  1186. {
  1187. delete main_loop;
  1188. irr_driver->updateConfigIfRelevant();
  1189. if(INetworkHttp::get())
  1190. INetworkHttp::get()->stopNetworkThread();
  1191. //delete in reverse order of what they were created in.
  1192. //see InitTuxkart()
  1193. Referee::cleanup();
  1194. if(ReplayPlay::get()) ReplayPlay::destroy();
  1195. if(race_manager) delete race_manager;
  1196. INetworkHttp::destroy();
  1197. if(news_manager) delete news_manager;
  1198. if(addons_manager) delete addons_manager;
  1199. if(network_manager) delete network_manager;
  1200. if(grand_prix_manager) delete grand_prix_manager;
  1201. if(highsco