2014-05-15 18:24:15 -04:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
2015-03-29 20:31:42 -04:00
|
|
|
// Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>
|
|
|
|
// Copyright (C) 2011-2015 Joerg Henrichs, Marianne Gagnon
|
2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
2008-06-12 20:53:52 -04:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 12:01:53 -04:00
|
|
|
// of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
|
2011-10-25 13:46:14 -04:00
|
|
|
/**
|
|
|
|
* \mainpage SuperTuxKart developer documentation
|
|
|
|
*
|
|
|
|
* This document contains the developer documentation for SuperTuxKart,
|
|
|
|
* including the list of modules, the list of classes, the API reference,
|
|
|
|
* and some pages that describe in more depth some parts of the code/engine.
|
|
|
|
*
|
|
|
|
* \section Overview
|
|
|
|
*
|
|
|
|
* Here is an overview of the high-level interactions between modules :
|
|
|
|
\dot
|
|
|
|
digraph interaction {
|
|
|
|
race -> modes
|
|
|
|
race -> tracks
|
|
|
|
race -> karts
|
|
|
|
modes -> tracks
|
|
|
|
modes -> karts
|
|
|
|
tracks -> graphics
|
|
|
|
karts -> graphics
|
|
|
|
tracks -> items
|
|
|
|
graphics -> irrlicht
|
|
|
|
guiengine -> irrlicht
|
|
|
|
states_screens -> guiengine
|
|
|
|
states_screens -> input
|
|
|
|
guiengine -> input
|
|
|
|
karts->physics
|
|
|
|
tracks->physics
|
|
|
|
karts -> controller
|
|
|
|
input->controller
|
|
|
|
tracks -> animations
|
|
|
|
physics -> animations
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
\enddot
|
|
|
|
|
2011-10-25 13:46:14 -04:00
|
|
|
Note that this graph is only an approximation because the real one would be
|
|
|
|
much too complicated :)
|
2013-05-29 18:04:35 -04:00
|
|
|
|
|
|
|
|
2011-10-25 13:46:14 -04:00
|
|
|
\section Modules
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-10-25 13:53:07 -04:00
|
|
|
\li \ref addonsgroup :
|
|
|
|
Handles add-ons that can be downloaded.
|
2011-10-25 13:46:14 -04:00
|
|
|
\li \ref animations :
|
|
|
|
This module manages interpolation-based animation (of position, rotation
|
|
|
|
and/or scale)
|
|
|
|
\li \ref audio :
|
|
|
|
This module handles audio (sound effects and music).
|
|
|
|
\li \ref challenges :
|
|
|
|
This module handles the challenge system, which locks features (tracks, karts
|
|
|
|
modes, etc.) until the user completes some task.
|
|
|
|
\li \ref config :
|
|
|
|
This module handles the user configuration, the supertuxkart configuration
|
|
|
|
file (which contains options usually not edited by the player) and the input
|
|
|
|
configuration file.
|
|
|
|
\li \ref graphics :
|
|
|
|
This module contains the core graphics engine, that is mostly a thin layer
|
|
|
|
on top of irrlicht providing some additional features we need for STK
|
|
|
|
(like particles, more scene node types, mesh manipulation tools, material
|
|
|
|
management, etc...)
|
|
|
|
\li \ref guiengine :
|
|
|
|
Contains the generic GUI engine (contains the widgets and the backing logic
|
|
|
|
for event handling, the skin, screens and dialogs). See module @ref states_screens
|
|
|
|
for the actual STK GUI screens. Note that all input comes through this module
|
|
|
|
too.
|
|
|
|
\li \ref widgetsgroup :
|
|
|
|
Contains the various types of widgets supported by the GUI engine.
|
|
|
|
\li \ref input :
|
|
|
|
Contains classes for input management (keyboard and gamepad)
|
|
|
|
\li \ref io :
|
|
|
|
Contains generic utility classes for file I/O (especially XML handling).
|
|
|
|
\li \ref items :
|
|
|
|
Defines the various collectibles and weapons of STK.
|
|
|
|
\li \ref karts :
|
|
|
|
Contains classes that deal with the properties, models and physics
|
|
|
|
of karts.
|
|
|
|
\li \ref controller :
|
|
|
|
Contains kart controllers, which are either human players or AIs
|
|
|
|
(this module thus contains the AIs)
|
|
|
|
\li \ref modes :
|
|
|
|
Contains the logic for the various game modes (race, follow the leader,
|
|
|
|
battle, etc.)
|
|
|
|
\li \ref physics :
|
|
|
|
Contains various physics utilities.
|
|
|
|
\li \ref race :
|
|
|
|
Contains the race information that is conceptually above what you can find
|
|
|
|
in group Modes. Handles highscores, grands prix, number of karts, which
|
|
|
|
track was selected, etc.
|
|
|
|
\li \ref states_screens :
|
|
|
|
Contains the various screens and dialogs of the STK user interface,
|
|
|
|
using the facilities of the guiengine module. Also contains the
|
|
|
|
stack of menus and handles state management (in-game vs menu).
|
|
|
|
\li \ref tracks :
|
|
|
|
Contains information about tracks, namely drivelines, checklines and track
|
|
|
|
objects.
|
|
|
|
\li \ref tutorial :
|
|
|
|
Work in progress
|
|
|
|
*/
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
#ifdef WIN32
|
|
|
|
# ifdef __CYGWIN__
|
|
|
|
# include <unistd.h>
|
|
|
|
# endif
|
2013-10-21 00:29:40 -04:00
|
|
|
# define WIN32_LEAN_AND_MEAN
|
2007-05-27 12:01:53 -04:00
|
|
|
# include <windows.h>
|
|
|
|
# ifdef _MSC_VER
|
|
|
|
# include <direct.h>
|
|
|
|
# endif
|
|
|
|
#else
|
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#include <stdexcept>
|
2007-11-21 20:20:57 -05:00
|
|
|
#include <cstdio>
|
|
|
|
#include <string>
|
2009-06-17 22:13:00 -04:00
|
|
|
#include <cstring>
|
2008-01-28 17:16:42 -05:00
|
|
|
#include <sstream>
|
|
|
|
#include <algorithm>
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2011-05-22 14:03:28 -04:00
|
|
|
#include <IEventReceiver.h>
|
2011-03-27 08:10:07 -04:00
|
|
|
|
2008-09-15 00:34:46 -04:00
|
|
|
#include "main_loop.hpp"
|
2013-09-02 16:53:55 -04:00
|
|
|
#include "achievements/achievements_manager.hpp"
|
2011-03-27 08:10:07 -04:00
|
|
|
#include "addons/addons_manager.hpp"
|
2011-05-12 19:51:00 -04:00
|
|
|
#include "addons/news_manager.hpp"
|
2010-04-21 13:24:02 -04:00
|
|
|
#include "audio/music_manager.hpp"
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "audio/sfx_manager.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "challenges/unlock_manager.hpp"
|
2014-09-16 08:02:20 -04:00
|
|
|
#include "config/hardware_stats.hpp"
|
2014-02-05 22:43:47 -05:00
|
|
|
#include "config/player_manager.hpp"
|
2014-02-17 04:10:29 -05:00
|
|
|
#include "config/player_profile.hpp"
|
2014-02-06 07:08:55 -05:00
|
|
|
#include "config/stk_config.hpp"
|
|
|
|
#include "config/user_config.hpp"
|
2015-03-11 20:28:35 -04:00
|
|
|
#include "graphics/central_settings.hpp"
|
2015-01-06 01:09:16 -05:00
|
|
|
#include "graphics/graphics_restrictions.hpp"
|
2009-03-11 23:49:31 -04:00
|
|
|
#include "graphics/irr_driver.hpp"
|
2009-06-02 08:37:29 -04:00
|
|
|
#include "graphics/material_manager.hpp"
|
2011-10-13 07:20:15 -04:00
|
|
|
#include "graphics/particle_kind_manager.hpp"
|
2011-09-13 20:48:49 -04:00
|
|
|
#include "graphics/referee.hpp"
|
2009-07-18 13:48:36 -04:00
|
|
|
#include "guiengine/engine.hpp"
|
2011-09-22 14:24:28 -04:00
|
|
|
#include "guiengine/event_handler.hpp"
|
2013-08-28 18:45:11 -04:00
|
|
|
#include "guiengine/dialog_queue.hpp"
|
2009-08-14 13:05:52 -04:00
|
|
|
#include "input/device_manager.hpp"
|
2014-02-26 00:34:46 -05:00
|
|
|
#include "input/input_manager.hpp"
|
2014-10-25 08:09:00 -04:00
|
|
|
#include "input/keyboard_device.hpp"
|
2012-01-01 16:19:13 -05:00
|
|
|
#include "input/wiimote_manager.hpp"
|
2011-03-27 08:10:07 -04:00
|
|
|
#include "io/file_manager.hpp"
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "items/attachment_manager.hpp"
|
|
|
|
#include "items/item_manager.hpp"
|
|
|
|
#include "items/projectile_manager.hpp"
|
2013-10-09 03:26:55 -04:00
|
|
|
#include "karts/controller/ai_base_lap_controller.hpp"
|
2012-03-19 16:21:11 -04:00
|
|
|
#include "karts/kart_properties.hpp"
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "karts/kart_properties_manager.hpp"
|
2012-05-06 20:10:33 -04:00
|
|
|
#include "modes/demo_world.hpp"
|
2009-08-23 11:42:58 -04:00
|
|
|
#include "modes/profile_world.hpp"
|
2015-11-11 17:53:12 -05:00
|
|
|
#include "network/network_config.hpp"
|
2016-02-23 00:29:57 -05:00
|
|
|
#include "network/network_string.hpp"
|
2015-11-12 01:52:04 -05:00
|
|
|
#include "network/servers_manager.hpp"
|
2015-10-26 17:23:59 -04:00
|
|
|
#include "network/stk_host.hpp"
|
2013-08-28 18:45:11 -04:00
|
|
|
#include "online/profile_manager.hpp"
|
2014-02-26 00:34:46 -05:00
|
|
|
#include "online/request_manager.hpp"
|
2009-06-02 21:36:48 -04:00
|
|
|
#include "race/grand_prix_manager.hpp"
|
|
|
|
#include "race/highscore_manager.hpp"
|
|
|
|
#include "race/history.hpp"
|
|
|
|
#include "race/race_manager.hpp"
|
2012-02-28 17:33:49 -05:00
|
|
|
#include "replay/replay_play.hpp"
|
|
|
|
#include "replay/replay_recorder.hpp"
|
2014-01-21 16:52:22 -05:00
|
|
|
#include "states_screens/main_menu_screen.hpp"
|
2014-05-16 21:43:05 -04:00
|
|
|
#include "states_screens/register_screen.hpp"
|
2009-10-04 19:59:05 -04:00
|
|
|
#include "states_screens/state_manager.hpp"
|
2014-05-05 07:17:46 -04:00
|
|
|
#include "states_screens/user_screen.hpp"
|
2011-03-31 06:15:09 -04:00
|
|
|
#include "states_screens/dialogs/message_dialog.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "tracks/track.hpp"
|
|
|
|
#include "tracks/track_manager.hpp"
|
2014-01-06 07:23:16 -05:00
|
|
|
#include "utils/command_line.hpp"
|
2011-03-30 19:31:29 -04:00
|
|
|
#include "utils/constants.hpp"
|
2013-12-01 23:27:55 -05:00
|
|
|
#include "utils/crash_reporting.hpp"
|
2011-09-22 14:08:04 -04:00
|
|
|
#include "utils/leak_check.hpp"
|
2013-01-13 19:38:07 -05:00
|
|
|
#include "utils/log.hpp"
|
2009-01-23 00:23:22 -05:00
|
|
|
#include "utils/translation.hpp"
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2013-12-01 23:27:55 -05:00
|
|
|
static void cleanSuperTuxKart();
|
2014-04-19 13:44:30 -04:00
|
|
|
static void cleanUserConfig();
|
2015-02-20 19:19:15 -05:00
|
|
|
void runUnitTests();
|
2013-12-01 23:27:55 -05:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
// ============================================================================
|
|
|
|
// gamepad visualisation screen
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
void gamepadVisualisation()
|
|
|
|
{
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
core::array<SJoystickInfo> irrlicht_gamepads;
|
|
|
|
irr_driver->getDevice()->activateJoysticks(irrlicht_gamepads);
|
|
|
|
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
struct Gamepad
|
|
|
|
{
|
2011-04-28 06:56:13 -04:00
|
|
|
s16 m_axis[SEvent::SJoystickEvent::NUMBER_OF_AXES];
|
|
|
|
bool m_button_state[SEvent::SJoystickEvent::NUMBER_OF_BUTTONS];
|
2011-01-10 11:49:34 -05:00
|
|
|
};
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
#define GAMEPAD_COUNT 8 // const won't work
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
class EventReceiver : public IEventReceiver
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Gamepad m_gamepads[GAMEPAD_COUNT];
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
EventReceiver()
|
|
|
|
{
|
|
|
|
for (int n=0; n<GAMEPAD_COUNT; n++)
|
|
|
|
{
|
|
|
|
Gamepad& g = m_gamepads[n];
|
2013-05-29 18:04:35 -04:00
|
|
|
for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_AXES; i++)
|
2011-10-05 00:15:19 -04:00
|
|
|
g.m_axis[i] = 0;
|
|
|
|
for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_BUTTONS; i++)
|
|
|
|
g.m_button_state[i] = false;
|
2011-01-10 11:49:34 -05:00
|
|
|
}
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
virtual bool OnEvent (const irr::SEvent &event)
|
|
|
|
{
|
|
|
|
switch (event.EventType)
|
|
|
|
{
|
|
|
|
case EET_JOYSTICK_INPUT_EVENT :
|
|
|
|
{
|
|
|
|
const SEvent::SJoystickEvent& evt = event.JoystickEvent;
|
|
|
|
if (evt.Joystick >= GAMEPAD_COUNT) return true;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
Gamepad& g = m_gamepads[evt.Joystick];
|
2011-10-05 00:15:19 -04:00
|
|
|
for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_AXES;i++)
|
2011-01-10 11:49:34 -05:00
|
|
|
{
|
|
|
|
g.m_axis[i] = evt.Axis[i];
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
for (int i=0; i<SEvent::SJoystickEvent::NUMBER_OF_BUTTONS;
|
2011-10-05 00:15:19 -04:00
|
|
|
i++)
|
2011-01-10 11:49:34 -05:00
|
|
|
{
|
|
|
|
g.m_button_state[i] = evt.IsButtonPressed(i);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-05-12 20:03:12 -04:00
|
|
|
case EET_KEY_INPUT_EVENT:
|
|
|
|
{
|
|
|
|
const SEvent::SKeyInput& evt = event.KeyInput;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-05-12 20:03:12 -04:00
|
|
|
if (evt.PressedDown)
|
|
|
|
{
|
2013-05-29 18:04:35 -04:00
|
|
|
if (evt.Key == KEY_RETURN || evt.Key == KEY_ESCAPE ||
|
2011-10-05 00:15:19 -04:00
|
|
|
evt.Key == KEY_SPACE)
|
2011-05-12 20:03:12 -04:00
|
|
|
{
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
default:
|
|
|
|
// don't care about others
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
EventReceiver* events = new EventReceiver();
|
|
|
|
irr_driver->getDevice()->setEventReceiver(events);
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (!irr_driver->getDevice()->run()) break;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
2011-10-05 00:15:19 -04:00
|
|
|
const core::dimension2du size = driver ->getCurrentRenderTargetSize();
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
driver->beginScene(true, true, video::SColor(255,0,0,0));
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
for (int n=0; n<GAMEPAD_COUNT; n++)
|
|
|
|
{
|
|
|
|
Gamepad& g = events->m_gamepads[n];
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
const int MARGIN = 10;
|
|
|
|
const int x = (n & 1 ? size.Width/2 + MARGIN : MARGIN );
|
|
|
|
const int w = size.Width/2 - MARGIN*2;
|
|
|
|
const int h = size.Height/(GAMEPAD_COUNT/2) - MARGIN*2;
|
|
|
|
const int y = size.Height/(GAMEPAD_COUNT/2)*(n/2) + MARGIN;
|
|
|
|
|
|
|
|
driver->draw2DRectangleOutline( core::recti(x, y, x+w, y+h) );
|
|
|
|
|
|
|
|
const int btn_y = y + 5;
|
|
|
|
const int btn_x = x + 5;
|
2013-05-29 18:04:35 -04:00
|
|
|
const int BTN_SIZE =
|
2011-10-05 00:15:19 -04:00
|
|
|
(w - 10)/SEvent::SJoystickEvent::NUMBER_OF_BUTTONS;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
for (int b=0; b<SEvent::SJoystickEvent::NUMBER_OF_BUTTONS; b++)
|
|
|
|
{
|
2013-01-13 20:02:38 -05:00
|
|
|
core::position2di pos(btn_x + b*BTN_SIZE, btn_y);
|
|
|
|
core::dimension2di size(BTN_SIZE, BTN_SIZE);
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
if (g.m_button_state[b])
|
|
|
|
{
|
2011-10-05 00:15:19 -04:00
|
|
|
driver->draw2DRectangle (video::SColor(255,255,0,0),
|
|
|
|
core::recti(pos, size));
|
2011-01-10 11:49:34 -05:00
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
driver->draw2DRectangleOutline( core::recti(pos, size) );
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
const int axis_y = btn_y + BTN_SIZE + 5;
|
|
|
|
const int axis_x = btn_x;
|
|
|
|
const int axis_w = w - 10;
|
2013-05-29 18:04:35 -04:00
|
|
|
const int axis_h = (h - BTN_SIZE - 15)
|
2011-10-05 00:15:19 -04:00
|
|
|
/ SEvent::SJoystickEvent::NUMBER_OF_AXES;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
for (int a=0; a<SEvent::SJoystickEvent::NUMBER_OF_AXES; a++)
|
|
|
|
{
|
|
|
|
const float rate = g.m_axis[a] / 32767.0f;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2013-01-13 20:02:38 -05:00
|
|
|
core::position2di pos(axis_x, axis_y + a*axis_h);
|
|
|
|
core::dimension2di size(axis_w, axis_h);
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-10-31 06:06:26 -04:00
|
|
|
// Assume a default deadzone value of 4096
|
|
|
|
const bool deadzone = (abs(g.m_axis[a]) < 4096);
|
2013-05-29 18:04:35 -04:00
|
|
|
|
|
|
|
core::recti fillbar(core::position2di(axis_x + axis_w/2,
|
2013-01-13 20:02:38 -05:00
|
|
|
axis_y + a*axis_h),
|
2013-05-29 18:04:35 -04:00
|
|
|
core::dimension2di( (int)(axis_w/2*rate),
|
2013-01-13 20:02:38 -05:00
|
|
|
axis_h) );
|
2011-01-10 11:49:34 -05:00
|
|
|
fillbar.repair(); // dimension may be negative
|
2011-01-11 16:06:19 -05:00
|
|
|
driver->draw2DRectangle (deadzone ? video::SColor(255,255,0,0)
|
|
|
|
: video::SColor(255,0,255,0),
|
2011-01-10 11:49:34 -05:00
|
|
|
fillbar);
|
|
|
|
driver->draw2DRectangleOutline( core::recti(pos, size) );
|
|
|
|
}
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
driver->endScene();
|
|
|
|
}
|
2013-12-01 23:27:55 -05:00
|
|
|
} // gamepadVisualisation
|
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
// ============================================================================
|
2014-06-04 09:10:20 -04:00
|
|
|
/** Sets the hat mesh name depending on the current christmas mode
|
2014-04-02 17:20:43 -04:00
|
|
|
* m_xmas_mode (0: use current date, 1: always on, 2: always off).
|
2013-12-01 23:27:55 -05:00
|
|
|
*/
|
|
|
|
void handleXmasMode()
|
|
|
|
{
|
|
|
|
bool xmas = false;
|
|
|
|
switch(UserConfigParams::m_xmas_mode)
|
|
|
|
{
|
2014-03-29 06:33:43 -04:00
|
|
|
case 0:
|
2013-12-01 23:27:55 -05:00
|
|
|
{
|
|
|
|
int day, month;
|
|
|
|
StkTime::getDate(&day, &month);
|
|
|
|
// Christmat hats are shown between 17. of December
|
|
|
|
// and 5th of January
|
|
|
|
xmas = (month == 12 && day>=17) || (month == 1 && day <=5);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: xmas = true; break;
|
|
|
|
default: xmas = false; break;
|
|
|
|
} // switch m_xmas_mode
|
2011-01-10 11:49:34 -05:00
|
|
|
|
2013-12-01 23:27:55 -05:00
|
|
|
if(xmas)
|
|
|
|
kart_properties_manager->setHatMeshName("christmas_hat.b3d");
|
|
|
|
} // handleXmasMode
|
2015-02-20 19:19:15 -05:00
|
|
|
// ============================================================================
|
|
|
|
/** Determines if Easter Ears should be used
|
|
|
|
* m_easter_ear_mode (0: use current date, 1: always on, 2: always off).
|
|
|
|
*/
|
|
|
|
bool isEasterMode(int day, int month, int year, int before_after_days)
|
|
|
|
{
|
|
|
|
switch (UserConfigParams::m_easter_ear_mode)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
// Compute Easter date, based on wikipedia formula
|
|
|
|
// http://en.wikipedia.org/wiki/Computus
|
2015-02-27 06:33:03 -05:00
|
|
|
int a = year % 19;
|
|
|
|
int b = year >> 2;
|
|
|
|
int c = int(floor(b / 25)) + 1;
|
|
|
|
int d = (c * 3) >> 2;
|
|
|
|
int e = ((a * 19) - int(floor((c * 8 + 5) / 25)) + d + 15) % 30;
|
|
|
|
e += (29578 - a - e * 32) >> 10;
|
|
|
|
e -= ((year % 7) + b - d + e + 2) % 7;
|
|
|
|
d = e >> 5;
|
|
|
|
int easter_day = e - d * 31;
|
|
|
|
int easter_month = d + 3;
|
2015-02-20 19:19:15 -05:00
|
|
|
|
|
|
|
int easter_start_day = easter_day - before_after_days;
|
|
|
|
int easter_start_month = easter_month;
|
|
|
|
if (easter_start_day < 1)
|
|
|
|
{
|
|
|
|
easter_start_day += 31; // Month is April, going into March
|
|
|
|
easter_start_month--;
|
|
|
|
}
|
|
|
|
int easter_end_day = easter_day + before_after_days;
|
|
|
|
int easter_end_month = easter_month;
|
|
|
|
int month_length = easter_end_month == 3 ? 31 : 30;
|
|
|
|
if (easter_end_day > month_length)
|
|
|
|
{
|
|
|
|
easter_end_day -= month_length;
|
|
|
|
easter_end_month++;
|
|
|
|
}
|
|
|
|
return (month > easter_start_month || (month == easter_start_month && day >= easter_start_day)) &&
|
|
|
|
(month < easter_end_month || (month == easter_end_month && day <= easter_end_day));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: return true; break;
|
|
|
|
default: return false; break;
|
|
|
|
} // switch m_xmas_mode
|
|
|
|
|
|
|
|
} // isEasterMode(day, month, year, before_after_days)
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
/** Wrapper around handleEasterEarMode(day, month, year, before_after_days).
|
|
|
|
*/
|
|
|
|
void handleEasterEarMode()
|
|
|
|
{
|
|
|
|
int day, month, year;
|
|
|
|
StkTime::getDate(&day, &month, &year);
|
|
|
|
if (isEasterMode(day, month, year, /*before_after_days*/5))
|
|
|
|
kart_properties_manager->setHatMeshName("easter_ears.b3d");
|
|
|
|
} // handleEasterMode
|
|
|
|
|
2014-04-27 17:51:24 -04:00
|
|
|
// ============================================================================
|
|
|
|
/** This function sets up all data structure for an immediate race start.
|
|
|
|
* It is used when the -N or -R command line options are used.
|
|
|
|
*/
|
|
|
|
void setupRaceStart()
|
|
|
|
{
|
|
|
|
// Skip the start screen. This esp. means that no login screen is
|
|
|
|
// displayed (if necessary), so we have to make sure there is
|
|
|
|
// a current player
|
|
|
|
PlayerManager::get()->enforceCurrentPlayer();
|
|
|
|
|
|
|
|
InputDevice *device;
|
|
|
|
|
|
|
|
// Use keyboard 0 by default in --no-start-screen
|
2014-10-25 08:09:00 -04:00
|
|
|
device = input_manager->getDeviceManager()->getKeyboard(0);
|
2014-04-27 17:51:24 -04:00
|
|
|
|
|
|
|
// Create player and associate player with keyboard
|
|
|
|
StateManager::get()->createActivePlayer(
|
2014-05-30 20:26:02 -04:00
|
|
|
PlayerManager::get()->getPlayer(0), device);
|
2014-04-27 17:51:24 -04:00
|
|
|
|
2014-06-12 02:54:09 -04:00
|
|
|
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))
|
2014-04-27 17:51:24 -04:00
|
|
|
{
|
|
|
|
Log::warn("main", "Kart '%s' is unknown so will use the "
|
|
|
|
"default kart.",
|
|
|
|
UserConfigParams::m_default_kart.c_str());
|
2016-01-11 21:00:45 -05:00
|
|
|
race_manager->setPlayerKart(0,
|
|
|
|
UserConfigParams::m_default_kart.getDefaultValue());
|
2014-04-27 17:51:24 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Set up race manager appropriately
|
2016-01-11 21:00:45 -05:00
|
|
|
race_manager->setPlayerKart(0, UserConfigParams::m_default_kart);
|
2014-04-27 17:51:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ASSIGN should make sure that only input from assigned devices
|
|
|
|
// is read.
|
2014-10-25 08:09:00 -04:00
|
|
|
input_manager->getDeviceManager()->setAssignMode(ASSIGN);
|
2014-06-27 01:39:33 -04:00
|
|
|
} // setupRaceStart
|
2011-01-10 11:49:34 -05:00
|
|
|
|
2013-12-01 23:27:55 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/** Prints help for command line options to stdout.
|
|
|
|
*/
|
2014-01-06 07:23:16 -05:00
|
|
|
void cmdLineHelp()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-09-25 04:25:44 -04:00
|
|
|
fprintf(stdout,
|
2008-04-20 20:09:23 -04:00
|
|
|
"Usage: %s [OPTIONS]\n\n"
|
2007-05-27 12:01:53 -04:00
|
|
|
"Run SuperTuxKart, a racing game with go-kart that features"
|
|
|
|
" the Tux and friends.\n\n"
|
|
|
|
"Options:\n"
|
2011-10-05 00:15:19 -04:00
|
|
|
" -N, --no-start-screen Immediately start race without showing a "
|
|
|
|
"menu.\n"
|
|
|
|
" -R, --race-now Same as -N but also skip the ready-set-go phase"
|
2013-06-09 16:04:07 -04:00
|
|
|
" and the music.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" -t, --track=NAME Start at track NAME.\n"
|
|
|
|
" --gp=NAME Start the specified Grand Prix.\n"
|
2014-03-06 14:30:52 -05:00
|
|
|
" --add-gp-dir=DIR Load Grand Prix in DIR. Setting will be saved "
|
|
|
|
"inconfig.xml under additional_gp_directory. Use "
|
|
|
|
"--add-gp-dir=\"\" to unset.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" --stk-config=FILE use ./data/FILE instead of "
|
2011-10-05 00:15:19 -04:00
|
|
|
"./data/stk_config.xml\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" -k, --numkarts=NUM Number of karts on the racetrack.\n"
|
|
|
|
" --kart=NAME Use kart number NAME.\n"
|
2013-05-29 18:04:35 -04:00
|
|
|
" --ai=a,b,... Use the karts a, b, ... for the AI.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" --laps=N Define number of laps to N.\n"
|
|
|
|
" --mode=N N=1 novice, N=2 driver, N=3 racer.\n"
|
|
|
|
" --type=N N=0 Normal, N=1 Time trial, N=2 FTL\n"
|
2012-02-05 15:56:45 -05:00
|
|
|
" --reverse Play track in reverse (if allowed)\n"
|
2009-08-24 01:56:53 -04:00
|
|
|
" -f, --fullscreen Select fullscreen display.\n"
|
|
|
|
" -w, --windowed Windowed display (default).\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" -s, --screensize=WxH Set the screen size (e.g. 320x200).\n"
|
2009-08-24 01:56:53 -04:00
|
|
|
" -v, --version Show version of SuperTuxKart.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" --trackdir=DIR A directory from which additional tracks are "
|
2011-10-05 00:15:19 -04:00
|
|
|
"loaded.\n"
|
2012-07-05 21:58:40 -04:00
|
|
|
" --profile-laps=n Enable automatic driven profile mode for n "
|
2011-10-05 00:15:19 -04:00
|
|
|
"laps.\n"
|
|
|
|
" --profile-time=n Enable automatic driven profile mode for n "
|
|
|
|
"seconds.\n"
|
2011-08-14 22:00:50 -04:00
|
|
|
" --no-graphics Do not display the actual race.\n"
|
2013-07-07 18:55:21 -04:00
|
|
|
" --with-profile Enables the profile mode.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" --demo-mode=t Enables demo mode after t seconds idle time in "
|
2012-05-06 20:10:33 -04:00
|
|
|
"main menu.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" --demo-tracks=t1,t2 List of tracks to be used in demo mode. No\n"
|
2012-05-06 20:10:33 -04:00
|
|
|
" spaces are allowed in the track names.\n"
|
2014-01-06 07:23:16 -05:00
|
|
|
" --demo-laps=n Number of laps in a demo.\n"
|
|
|
|
" --demo-karts=n Number of karts to use in a demo.\n"
|
2012-03-01 21:05:53 -05:00
|
|
|
" --ghost Replay ghost data together with one player kart.\n"
|
2011-08-14 22:00:50 -04:00
|
|
|
// " --history Replay history file 'history.dat'.\n"
|
2011-10-05 00:15:19 -04:00
|
|
|
// " --history=n Replay history file 'history.dat' using:\n"
|
|
|
|
// " n=1: recorded positions\n"
|
|
|
|
// " n=2: recorded key strokes\n"
|
2015-11-01 16:11:51 -05:00
|
|
|
" --server=name Start a server (not a playing client).\n"
|
2015-11-18 01:24:56 -05:00
|
|
|
" --lan-server=name Start a LAN server (not a playing client).\n"
|
2016-02-09 21:32:39 -05:00
|
|
|
" --server-password= Sets a password for a server (both client&server).\n"
|
2015-01-07 21:32:50 -05:00
|
|
|
" --login=s Automatically log in (set the login).\n"
|
|
|
|
" --password=s Automatically log in (set the password).\n"
|
2013-07-31 14:03:11 -04:00
|
|
|
" --port=n Port number to use.\n"
|
|
|
|
" --max-players=n Maximum number of clients (server only).\n"
|
2013-04-30 03:17:02 -04:00
|
|
|
" --no-console Does not write messages in the console but to\n"
|
2013-05-29 19:44:28 -04:00
|
|
|
" stdout.log.\n"
|
2013-04-30 03:17:02 -04:00
|
|
|
" --console Write messages in the console and files\n"
|
2009-08-24 01:56:53 -04:00
|
|
|
" -h, --help Show this help.\n"
|
2015-04-23 11:40:20 -04:00
|
|
|
" --log=N Set the verbosity to a value between\n"
|
|
|
|
" 0 (Debug) and 5 (Only Fatal messages)\n"
|
2015-07-25 20:06:42 -04:00
|
|
|
" --root=DIR Path to add to the list of STK root directories.\n"
|
|
|
|
" You can specify more than one by separating them\n"
|
|
|
|
" with colons (:).\n"
|
2007-05-27 12:01:53 -04:00
|
|
|
"\n"
|
|
|
|
"You can visit SuperTuxKart's homepage at "
|
2014-01-06 07:23:16 -05:00
|
|
|
"http://supertuxkart.sourceforge.net\n\n",
|
|
|
|
CommandLine::getExecName().c_str()
|
2007-05-27 12:01:53 -04:00
|
|
|
);
|
|
|
|
} // cmdLineHelp
|
|
|
|
|
|
|
|
//=============================================================================
|
2015-04-23 14:08:19 -04:00
|
|
|
/** For base options that modify the output (loglevel/color) or exit right
|
|
|
|
* after being processed (version/help).
|
2009-08-24 01:56:53 -04:00
|
|
|
*/
|
2015-04-23 14:08:19 -04:00
|
|
|
int handleCmdLineOutputModifier()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-04-22 00:24:32 -04:00
|
|
|
if (CommandLine::has("--help") || CommandLine::has("-help") ||
|
|
|
|
CommandLine::has("-h"))
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
cmdLineHelp();
|
2014-04-19 13:44:30 -04:00
|
|
|
cleanUserConfig();
|
2014-01-06 07:23:16 -05:00
|
|
|
exit(0);
|
|
|
|
}
|
2014-03-28 17:10:43 -04:00
|
|
|
|
|
|
|
if(CommandLine::has("--version") || CommandLine::has("-v"))
|
|
|
|
{
|
|
|
|
Log::info("main", "==============================");
|
|
|
|
Log::info("main", "SuperTuxKart, %s.", STK_VERSION ) ;
|
|
|
|
// IRRLICHT_VERSION_SVN
|
|
|
|
Log::info("main", "Irrlicht version %i.%i.%i (%s)",
|
|
|
|
IRRLICHT_VERSION_MAJOR , IRRLICHT_VERSION_MINOR,
|
|
|
|
IRRLICHT_VERSION_REVISION, IRRLICHT_SDK_VERSION );
|
|
|
|
Log::info("main", "==============================");
|
2014-04-19 13:44:30 -04:00
|
|
|
cleanUserConfig();
|
2014-03-28 17:10:43 -04:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2015-04-23 14:08:19 -04:00
|
|
|
int n;
|
|
|
|
if(CommandLine::has("--log", &n))
|
|
|
|
Log::setLogLevel(n);
|
|
|
|
|
|
|
|
if(CommandLine::has("--log=nocolor"))
|
|
|
|
{
|
|
|
|
Log::disableColor();
|
|
|
|
Log::verbose("main", "Colours disabled.");
|
|
|
|
}
|
|
|
|
|
|
|
|
if(CommandLine::has("--console"))
|
|
|
|
UserConfigParams::m_log_errors_to_console=true;
|
|
|
|
if(CommandLine::has("--no-console"))
|
|
|
|
UserConfigParams::m_log_errors_to_console=false;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/** For base options that don't need much to be inited (and, in some cases,
|
|
|
|
* that need to be read before initing stuff) - it only assumes that
|
|
|
|
* user config is loaded (necessary to check for blacklisted screen
|
|
|
|
* resolutions), but nothing else (esp. not kart_properties_manager and
|
|
|
|
* track_manager, since their search path might be extended by command
|
|
|
|
* line options).
|
|
|
|
*/
|
|
|
|
int handleCmdLinePreliminary()
|
|
|
|
{
|
|
|
|
if(CommandLine::has("--gamepad-visualisation") || // only BE
|
2014-03-28 17:10:43 -04:00
|
|
|
CommandLine::has("--gamepad-visualization") ) // both AE and BE
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_gamepad_visualisation=true;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--debug=memory"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_verbosity |= UserConfigParams::LOG_MEMORY;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--debug=addons"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_verbosity |= UserConfigParams::LOG_ADDONS;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--debug=mgui"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_verbosity |= UserConfigParams::LOG_GUI;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--debug=flyable"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_verbosity |= UserConfigParams::LOG_FLYABLE;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--debug=mist"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_verbosity |= UserConfigParams::LOG_MISC;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--debug=all") )
|
|
|
|
UserConfigParams::m_verbosity |= UserConfigParams::LOG_ALL;
|
2014-01-21 16:52:22 -05:00
|
|
|
if(CommandLine::has("--online"))
|
|
|
|
MainMenuScreen::m_enable_online=true;
|
2014-01-06 07:23:16 -05:00
|
|
|
|
|
|
|
std::string s;
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--stk-config", &s))
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
stk_config->load(file_manager->getAsset(s));
|
2014-01-06 07:28:24 -05:00
|
|
|
Log::info("main", "STK config will be read from %s.",s.c_str());
|
2014-01-06 07:23:16 -05:00
|
|
|
}
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--trackdir", &s))
|
2014-01-06 07:23:16 -05:00
|
|
|
TrackManager::addTrackSearchDir(s);
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--kartdir", &s))
|
2014-01-06 07:23:16 -05:00
|
|
|
KartPropertiesManager::addKartSearchDir(s);
|
|
|
|
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--no-graphics") || CommandLine::has("-l"))
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
ProfileWorld::disableGraphics();
|
|
|
|
UserConfigParams::m_log_errors_to_console=true;
|
|
|
|
}
|
|
|
|
|
2014-03-28 17:10:43 -04:00
|
|
|
if(CommandLine::has("--screensize", &s) || CommandLine::has("-s", &s))
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
//Check if fullscreen and new res is blacklisted
|
|
|
|
int width, height;
|
|
|
|
if (sscanf(s.c_str(), "%dx%d", &width, &height) == 2)
|
2009-06-07 11:20:51 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
// Reassemble the string in case that the original width or
|
2014-03-29 06:33:43 -04:00
|
|
|
// height contained a leading 0
|
2009-06-07 11:20:51 -04:00
|
|
|
std::ostringstream o;
|
2014-01-06 07:23:16 -05:00
|
|
|
o << width << "x" << height;
|
2009-12-17 19:36:35 -05:00
|
|
|
std::string res = o.str();
|
2014-01-06 07:23:16 -05:00
|
|
|
if (!UserConfigParams::m_fullscreen ||
|
|
|
|
std::find(UserConfigParams::m_blacklist_res.begin(),
|
|
|
|
UserConfigParams::m_blacklist_res.end(),res) ==
|
|
|
|
UserConfigParams::m_blacklist_res.end())
|
2009-06-07 11:20:51 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_prev_width =
|
|
|
|
UserConfigParams::m_width = width;
|
|
|
|
UserConfigParams::m_prev_height =
|
|
|
|
UserConfigParams::m_height = height;
|
|
|
|
Log::verbose("main", "You choose to use %dx%d.",
|
|
|
|
(int)UserConfigParams::m_width,
|
|
|
|
(int)UserConfigParams::m_height );
|
2009-06-07 11:20:51 -04:00
|
|
|
}
|
|
|
|
else
|
2014-01-06 07:23:16 -05:00
|
|
|
Log::warn("main", "Resolution %s has been blacklisted, so "
|
|
|
|
"it is not available!", res.c_str());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
else
|
2009-06-07 11:20:51 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
Log::fatal("main", "Error: --screensize argument must be "
|
|
|
|
"given as WIDTHxHEIGHT");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(CommandLine::has("--fullscreen") || CommandLine::has("-f"))
|
|
|
|
{
|
|
|
|
// Check that current res is not blacklisted
|
|
|
|
std::ostringstream o;
|
|
|
|
o << UserConfigParams::m_width << "x" << UserConfigParams::m_height;
|
|
|
|
std::string res = o.str();
|
|
|
|
if (std::find(UserConfigParams::m_blacklist_res.begin(),
|
|
|
|
UserConfigParams::m_blacklist_res.end(),res)
|
|
|
|
== UserConfigParams::m_blacklist_res.end())
|
|
|
|
UserConfigParams::m_fullscreen = true;
|
|
|
|
else
|
|
|
|
Log::warn("main", "Resolution %s has been blacklisted, so it "
|
|
|
|
"is not available!", res.c_str());
|
|
|
|
}
|
2014-03-28 17:10:43 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--windowed") || CommandLine::has("-w"))
|
|
|
|
UserConfigParams::m_fullscreen = false;
|
|
|
|
|
2014-03-28 17:10:43 -04:00
|
|
|
// Enable loading grand prix from local directory
|
2014-03-05 06:11:20 -05:00
|
|
|
if(CommandLine::has("--add-gp-dir", &s))
|
|
|
|
{
|
|
|
|
// Ensure that the path ends with a /
|
|
|
|
if (s[s.size()] == '/')
|
|
|
|
UserConfigParams::m_additional_gp_directory = s;
|
|
|
|
else
|
|
|
|
UserConfigParams::m_additional_gp_directory = s + "/";
|
|
|
|
|
2014-03-06 05:30:51 -05:00
|
|
|
Log::info("main", "Additional Grand Prix's will be loaded from %s",
|
|
|
|
UserConfigParams::m_additional_gp_directory.c_str());
|
2014-03-05 06:11:20 -05:00
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
int n;
|
|
|
|
if(CommandLine::has("--xmas", &n))
|
|
|
|
UserConfigParams::m_xmas_mode = n;
|
2015-02-20 19:19:15 -05:00
|
|
|
if (CommandLine::has("--easter", &n))
|
|
|
|
UserConfigParams::m_easter_ear_mode = n;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2009-06-07 11:20:51 -04:00
|
|
|
return 0;
|
2013-12-01 23:27:55 -05:00
|
|
|
} // handleCmdLinePreliminary
|
2009-06-07 11:20:51 -04:00
|
|
|
|
2009-08-24 01:56:53 -04:00
|
|
|
// ============================================================================
|
|
|
|
/** Handles command line options.
|
|
|
|
* \param argc Number of command line options
|
|
|
|
*/
|
2014-01-06 07:23:16 -05:00
|
|
|
int handleCmdLine()
|
2009-06-07 11:20:51 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
// Some generic variables used in scanning:
|
2009-06-07 11:20:51 -04:00
|
|
|
int n;
|
2014-01-06 07:23:16 -05:00
|
|
|
std::string s;
|
2009-09-03 23:56:47 -04:00
|
|
|
|
2013-07-09 08:42:44 -04:00
|
|
|
bool try_login = false;
|
|
|
|
irr::core::stringw login, password;
|
2009-09-03 23:56:47 -04:00
|
|
|
|
2015-01-07 18:05:19 -05:00
|
|
|
if (CommandLine::has("--unit-testing"))
|
|
|
|
UserConfigParams::m_unit_testing = true;
|
|
|
|
if (CommandLine::has("--gamepad-debug"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_gamepad_debug=true;
|
2015-01-07 17:05:04 -05:00
|
|
|
if (CommandLine::has("--keyboard-debug"))
|
|
|
|
UserConfigParams::m_keyboard_debug = true;
|
|
|
|
if (CommandLine::has("--wiimote-debug"))
|
2014-01-06 07:23:16 -05:00
|
|
|
UserConfigParams::m_wiimote_debug = true;
|
|
|
|
if(CommandLine::has("--tutorial-debug"))
|
2010-12-31 00:04:59 -05:00
|
|
|
UserConfigParams::m_tutorial_debug = true;
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has( "--track-debug",&n))
|
|
|
|
UserConfigParams::m_track_debug=n;
|
|
|
|
if(CommandLine::has( "--track-debug"))
|
|
|
|
UserConfigParams::m_track_debug=1;
|
|
|
|
if(CommandLine::has("--material-debug"))
|
|
|
|
UserConfigParams::m_material_debug = true;
|
|
|
|
if(CommandLine::has("--ftl-debug"))
|
|
|
|
UserConfigParams::m_ftl_debug = true;
|
|
|
|
if(CommandLine::has("--slipstream-debug"))
|
|
|
|
UserConfigParams::m_slipstream_debug=true;
|
|
|
|
if(CommandLine::has("--rendering-debug"))
|
|
|
|
UserConfigParams::m_rendering_debug=true;
|
|
|
|
if(CommandLine::has("--ai-debug"))
|
|
|
|
AIBaseController::enableDebug();
|
2015-09-28 17:58:24 -04:00
|
|
|
if (CommandLine::has("--fps-debug"))
|
|
|
|
UserConfigParams::m_fps_debug = true;
|
2014-01-06 07:23:16 -05:00
|
|
|
|
|
|
|
if(UserConfigParams::m_artist_debug_mode)
|
|
|
|
{
|
|
|
|
if(CommandLine::has("--camera-wheel-debug"))
|
|
|
|
UserConfigParams::m_camera_debug=2;
|
|
|
|
if(CommandLine::has("--camera-debug"))
|
2010-04-26 19:28:11 -04:00
|
|
|
UserConfigParams::m_camera_debug=1;
|
2015-07-02 02:39:13 -04:00
|
|
|
if(CommandLine::has("--camera-kart-debug"))
|
|
|
|
UserConfigParams::m_camera_debug=4;
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--physics-debug"))
|
2011-11-30 20:14:10 -05:00
|
|
|
UserConfigParams::m_physics_debug=1;
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--check-debug"))
|
2010-04-19 08:37:45 -04:00
|
|
|
UserConfigParams::m_check_debug=true;
|
2014-01-06 07:23:16 -05:00
|
|
|
}
|
2011-02-20 00:11:26 -05:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
// Networking command lines
|
2015-11-18 01:24:56 -05:00
|
|
|
NetworkConfig::get()->
|
|
|
|
setMaxPlayers(UserConfigParams::m_server_max_players);
|
|
|
|
if(CommandLine::has("--server", &s))
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
2015-11-11 17:53:12 -05:00
|
|
|
NetworkConfig::get()->setServerName(core::stringw(s.c_str()));
|
2015-11-18 01:24:56 -05:00
|
|
|
NetworkConfig::get()->setIsServer(true);
|
|
|
|
NetworkConfig::get()->setIsWAN();
|
2015-11-11 17:53:12 -05:00
|
|
|
STKHost::create();
|
2015-11-18 01:24:56 -05:00
|
|
|
Log::info("main", "Creating a WAN server '%s'.", s.c_str());
|
|
|
|
}
|
|
|
|
if (CommandLine::has("--lan-server", &s))
|
|
|
|
{
|
|
|
|
NetworkConfig::get()->setServerName(core::stringw(s.c_str()));
|
|
|
|
NetworkConfig::get()->setIsServer(true);
|
|
|
|
NetworkConfig::get()->setIsLAN();
|
|
|
|
STKHost::create();
|
|
|
|
Log::info("main", "Creating a LAN server '%s'.", s.c_str());
|
2015-10-23 21:39:17 -04:00
|
|
|
}
|
2016-02-09 21:32:39 -05:00
|
|
|
if (CommandLine::has("--server-password", &s))
|
|
|
|
{
|
|
|
|
NetworkConfig::get()->setPassword(s);
|
|
|
|
}
|
2013-04-17 03:18:23 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--max-players", &n))
|
|
|
|
UserConfigParams::m_server_max_players=n;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--login", &s) )
|
|
|
|
{
|
|
|
|
login = s.c_str();
|
|
|
|
try_login = true;
|
|
|
|
} // --login
|
|
|
|
|
|
|
|
if(CommandLine::has("--password", &s))
|
|
|
|
password = s.c_str();
|
|
|
|
|
|
|
|
// Race parameters
|
|
|
|
if(CommandLine::has("--kartsize-debug"))
|
|
|
|
{
|
2015-10-23 21:39:17 -04:00
|
|
|
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts();
|
|
|
|
i++)
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
const KartProperties *km =
|
|
|
|
kart_properties_manager->getKartById(i);
|
|
|
|
Log::info("main", "%s:\t%swidth: %f length: %f height: %f "
|
|
|
|
"mesh-buffer count %d",
|
|
|
|
km->getIdent().c_str(),
|
|
|
|
(km->getIdent().size()<7) ? "\t" : "",
|
|
|
|
km->getMasterKartModel().getWidth(),
|
|
|
|
km->getMasterKartModel().getLength(),
|
|
|
|
km->getMasterKartModel().getHeight(),
|
|
|
|
km->getMasterKartModel().getModel()
|
|
|
|
->getMeshBufferCount());
|
|
|
|
} // for i
|
|
|
|
} // --kartsize-debug
|
|
|
|
|
|
|
|
if(CommandLine::has("--kart", &s))
|
|
|
|
{
|
2014-12-19 00:08:35 -05:00
|
|
|
const KartProperties *prop = kart_properties_manager->getKart(s);
|
|
|
|
if (prop)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-12-19 00:08:35 -05:00
|
|
|
UserConfigParams::m_default_kart = s;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-12-19 00:08:35 -05:00
|
|
|
// if a player was added with -N, change its kart.
|
|
|
|
// Otherwise, nothing to do, kart choice will be picked
|
|
|
|
// up upon player creation.
|
|
|
|
if (StateManager::get()->activePlayerCount() > 0)
|
2008-05-08 10:32:51 -04:00
|
|
|
{
|
2016-01-11 21:00:45 -05:00
|
|
|
race_manager->setPlayerKart(0, s);
|
2009-02-10 00:30:59 -05:00
|
|
|
}
|
2014-12-19 00:08:35 -05:00
|
|
|
Log::verbose("main", "You chose to use kart '%s'.",
|
|
|
|
s.c_str());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2014-12-19 00:08:35 -05:00
|
|
|
else
|
2010-07-25 18:35:53 -04:00
|
|
|
{
|
2014-12-19 00:08:35 -05:00
|
|
|
Log::warn("main", "Kart '%s' not found, ignored.",
|
|
|
|
s.c_str());
|
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
} // if --kart
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--ai", &s))
|
|
|
|
{
|
|
|
|
const std::vector<std::string> l=StringUtils::split(std::string(s),',');
|
|
|
|
race_manager->setDefaultAIKartList(l);
|
|
|
|
// Add 1 for the player kart
|
2014-09-23 00:41:32 -04:00
|
|
|
race_manager->setNumKarts((int)l.size()+1);
|
2014-01-06 07:23:16 -05:00
|
|
|
} // --ai
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2015-08-31 03:09:51 -04:00
|
|
|
if(CommandLine::has( "--mode", &s) || CommandLine::has( "--difficulty", &s))
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
int n = atoi(s.c_str());
|
|
|
|
if(n<0 || n>RaceManager::DIFFICULTY_LAST)
|
|
|
|
Log::warn("main", "Invalid difficulty '%s' - ignored.\n",
|
|
|
|
s.c_str());
|
|
|
|
else
|
|
|
|
race_manager->setDifficulty(RaceManager::Difficulty(n));
|
|
|
|
} // --mode
|
|
|
|
|
|
|
|
if(CommandLine::has("--type", &n))
|
|
|
|
{
|
|
|
|
switch (n)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
case 0: race_manager->setMinorMode(RaceManager::MINOR_MODE_NORMAL_RACE);
|
|
|
|
break;
|
|
|
|
case 1: race_manager->setMinorMode(RaceManager::MINOR_MODE_TIME_TRIAL);
|
|
|
|
break;
|
|
|
|
case 2: race_manager->setMinorMode(RaceManager::MINOR_MODE_FOLLOW_LEADER);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Log::warn("main", "Invalid race type '%d' - ignored.", n);
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
} // --type
|
2013-04-17 03:00:30 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--track", &s) || CommandLine::has("-t", &s))
|
|
|
|
{
|
2014-12-19 00:08:35 -05:00
|
|
|
race_manager->setTrack(s);
|
|
|
|
Log::verbose("main", "You choose to start in track '%s'.",
|
|
|
|
s.c_str());
|
2013-04-17 03:00:30 -04:00
|
|
|
|
2014-12-19 00:08:35 -05:00
|
|
|
Track* t = track_manager->getTrack(s);
|
|
|
|
if (!t)
|
|
|
|
{
|
|
|
|
Log::warn("main", "Can't find track named '%s'.", s.c_str());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2014-12-19 00:08:35 -05:00
|
|
|
else if (t->isArena())
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-12-19 00:08:35 -05:00
|
|
|
//if it's arena, don't create ai karts
|
|
|
|
const std::vector<std::string> l;
|
|
|
|
race_manager->setDefaultAIKartList(l);
|
|
|
|
// Add 1 for the player kart
|
|
|
|
race_manager->setNumKarts(1);
|
|
|
|
race_manager->setMinorMode(RaceManager::MINOR_MODE_3_STRIKES);
|
|
|
|
}
|
|
|
|
else if (t->isSoccer())
|
|
|
|
{
|
|
|
|
//if it's soccer, don't create ai karts
|
|
|
|
const std::vector<std::string> l;
|
|
|
|
race_manager->setDefaultAIKartList(l);
|
|
|
|
// Add 1 for the player kart
|
|
|
|
race_manager->setNumKarts(1);
|
|
|
|
race_manager->setMinorMode(RaceManager::MINOR_MODE_SOCCER);
|
2010-03-24 19:52:41 -04:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
} // --track
|
|
|
|
|
|
|
|
if(CommandLine::has("--gp", &s))
|
|
|
|
{
|
|
|
|
race_manager->setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX);
|
2014-07-07 23:20:53 -04:00
|
|
|
const GrandPrixData *gp = grand_prix_manager->getGrandPrix(s);
|
2014-01-06 07:23:16 -05:00
|
|
|
|
|
|
|
if (!gp)
|
2013-07-08 10:36:39 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
Log::warn("main", "There is no GP named '%s'.", s.c_str());
|
|
|
|
return 0;
|
2013-07-08 10:36:39 -04:00
|
|
|
}
|
2014-09-01 19:32:12 -04:00
|
|
|
race_manager->setGrandPrix(*gp);
|
2014-01-06 07:23:16 -05:00
|
|
|
} // --gp
|
|
|
|
|
|
|
|
if(CommandLine::has("--numkarts", &n) ||CommandLine::has("-k", &n))
|
|
|
|
{
|
|
|
|
UserConfigParams::m_num_karts = n;
|
|
|
|
if(UserConfigParams::m_num_karts > stk_config->m_max_karts)
|
|
|
|
{
|
|
|
|
Log::warn("main", "Number of karts reset to maximum number %d.",
|
|
|
|
stk_config->m_max_karts);
|
|
|
|
UserConfigParams::m_num_karts = stk_config->m_max_karts;
|
|
|
|
}
|
|
|
|
race_manager->setNumKarts( UserConfigParams::m_num_karts );
|
|
|
|
Log::verbose("main", "%d karts will be used.",
|
|
|
|
(int)UserConfigParams::m_num_karts);
|
|
|
|
} // --numkarts
|
|
|
|
|
2014-03-29 06:33:43 -04:00
|
|
|
if(CommandLine::has( "--no-start-screen") ||
|
2014-01-06 07:23:16 -05:00
|
|
|
CommandLine::has("-N") )
|
|
|
|
UserConfigParams::m_no_start_screen = true;
|
|
|
|
if(CommandLine::has("--race-now") || CommandLine::has("-R"))
|
|
|
|
{
|
|
|
|
UserConfigParams::m_no_start_screen = true;
|
|
|
|
UserConfigParams::m_race_now = true;
|
|
|
|
} // --race-now
|
|
|
|
|
|
|
|
if(CommandLine::has("--laps", &s))
|
|
|
|
{
|
|
|
|
int laps = atoi(s.c_str());
|
|
|
|
if (laps < 0)
|
2011-07-27 08:11:11 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
Log::error("main", "Invalid number of laps: %s.\n", s.c_str());
|
|
|
|
return 0;
|
2011-07-27 08:11:11 -04:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
else
|
2012-02-27 00:52:17 -05:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
Log::verbose("main", "You choose to have %d laps.", laps);
|
|
|
|
race_manager->setNumLaps(laps);
|
2012-02-27 00:52:17 -05:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
} // --laps
|
2010-03-10 05:14:36 -05:00
|
|
|
|
2014-05-14 02:47:21 -04:00
|
|
|
if(CommandLine::has("--profile-laps", &n))
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
if (n < 0)
|
|
|
|
{
|
|
|
|
Log::error("main", "Invalid number of profile-laps: %i.", n );
|
|
|
|
return 0;
|
2008-10-06 09:40:11 -04:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
else
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
Log::verbose("main", "Profiling %d laps.",n);
|
2010-03-10 05:14:36 -05:00
|
|
|
UserConfigParams::m_no_start_screen = true;
|
2014-01-06 07:23:16 -05:00
|
|
|
ProfileWorld::setProfileModeLaps(n);
|
|
|
|
race_manager->setNumLaps(n);
|
|
|
|
}
|
|
|
|
} // --profile-laps
|
2010-03-10 05:14:36 -05:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--profile-time", &n))
|
|
|
|
{
|
|
|
|
Log::verbose("main", "Profiling: %d seconds.", n);
|
|
|
|
UserConfigParams::m_no_start_screen = true;
|
|
|
|
ProfileWorld::setProfileModeTime((float)n);
|
|
|
|
race_manager->setNumLaps(999999); // profile end depends on time
|
|
|
|
} // --profile-time
|
|
|
|
|
|
|
|
if(CommandLine::has("--with-profile") )
|
|
|
|
{
|
|
|
|
// Set default profile mode of 1 lap if we haven't already set one
|
|
|
|
if (!ProfileWorld::isProfileMode()) {
|
|
|
|
UserConfigParams::m_no_start_screen = true;
|
|
|
|
ProfileWorld::setProfileModeLaps(1);
|
|
|
|
race_manager->setNumLaps(1);
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2014-01-06 07:23:16 -05:00
|
|
|
} // --with-profile
|
|
|
|
|
|
|
|
if(CommandLine::has("--ghost"))
|
|
|
|
ReplayPlay::create();
|
|
|
|
|
|
|
|
if(CommandLine::has("--history", &n))
|
|
|
|
{
|
|
|
|
history->doReplayHistory( (History::HistoryReplayMode)n);
|
|
|
|
// Force the no-start screen flag, since this initialises
|
|
|
|
// the player structures correctly.
|
|
|
|
UserConfigParams::m_no_start_screen = true;
|
|
|
|
} // --history=%d
|
|
|
|
|
|
|
|
if(CommandLine::has("--history")) // handy default for --history=1
|
|
|
|
{
|
|
|
|
history->doReplayHistory(History::HISTORY_POSITION);
|
|
|
|
// Force the no-start screen flag, since this initialises
|
|
|
|
// the player structures correctly.
|
|
|
|
UserConfigParams::m_no_start_screen = true;
|
|
|
|
} // --history
|
|
|
|
|
|
|
|
// Demo mode
|
|
|
|
if(CommandLine::has("--demo-mode", &s))
|
|
|
|
{
|
2015-10-04 10:54:14 -04:00
|
|
|
float t = 0;
|
2014-01-06 07:23:16 -05:00
|
|
|
StringUtils::fromString(s, t);
|
|
|
|
DemoWorld::enableDemoMode(t);
|
|
|
|
// The default number of laps is taken from ProfileWorld and
|
|
|
|
// is 0. So set a more useful default for demo mode.
|
|
|
|
DemoWorld::setNumLaps(2);
|
|
|
|
} // --demo-mode
|
|
|
|
|
|
|
|
if(CommandLine::has("--demo-laps", &n))
|
|
|
|
{
|
|
|
|
// Note that we use a separate setting for demo mode to avoid the
|
|
|
|
// problem that someone plays a game, and in further demos then
|
|
|
|
// the wrong (i.e. last selected) number of laps would be used
|
|
|
|
DemoWorld::setNumLaps(n);
|
|
|
|
} // --demo-laps
|
|
|
|
|
|
|
|
if(CommandLine::has("--demo-karts", &n))
|
|
|
|
{
|
|
|
|
// Note that we use a separate setting for demo mode to avoid the
|
|
|
|
// problem that someone plays a game, and in further demos then
|
|
|
|
// the wrong (i.e. last selected) number of karts would be used
|
|
|
|
DemoWorld::setNumKarts(n);
|
|
|
|
} // --demo-karts
|
|
|
|
|
|
|
|
if(CommandLine::has("--demo-tracks", &s))
|
|
|
|
DemoWorld::setTracks(StringUtils::split(s,','));
|
|
|
|
|
2013-02-05 06:11:25 -05:00
|
|
|
#ifdef ENABLE_WIIUSE
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--wii"))
|
|
|
|
WiimoteManager::enable();
|
2013-02-05 06:11:25 -05:00
|
|
|
#endif
|
2014-01-06 07:23:16 -05:00
|
|
|
|
2010-02-24 19:40:25 -05:00
|
|
|
#ifdef __APPLE__
|
2014-01-06 07:23:16 -05:00
|
|
|
// on OS X, sometimes the Finder will pass a -psn* something parameter
|
|
|
|
// to the application --> ignore it
|
|
|
|
CommandLine::has("-psn");
|
2010-02-24 19:40:25 -05:00
|
|
|
#endif
|
2013-12-01 23:27:55 -05:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
CommandLine::reportInvalidParameters();
|
|
|
|
|
2009-08-23 11:42:58 -04:00
|
|
|
if(ProfileWorld::isProfileMode())
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2013-05-29 18:04:35 -04:00
|
|
|
UserConfigParams::m_sfx = false; // Disable sound effects
|
2009-06-20 21:10:43 -04:00
|
|
|
UserConfigParams::m_music = false;// and music when profiling
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
|
2013-07-09 08:42:44 -04:00
|
|
|
if (try_login)
|
|
|
|
{
|
|
|
|
irr::core::stringw s;
|
2014-01-14 06:47:25 -05:00
|
|
|
Online::XMLRequest* request =
|
2014-05-08 08:17:15 -04:00
|
|
|
PlayerManager::requestSignIn(login, password);
|
2013-07-31 14:03:11 -04:00
|
|
|
|
|
|
|
if (request->isSuccess())
|
|
|
|
{
|
|
|
|
Log::info("Main", "Logged in from command line.");
|
|
|
|
}
|
2013-07-09 08:42:44 -04:00
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
return 1;
|
2010-09-29 19:09:53 -04:00
|
|
|
} // handleCmdLine
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
//=============================================================================
|
2009-08-27 02:22:52 -04:00
|
|
|
/** Initialises the minimum number of managers to get access to user_config.
|
|
|
|
*/
|
2014-01-06 07:23:16 -05:00
|
|
|
void initUserConfig()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2015-01-05 15:48:32 -05:00
|
|
|
file_manager = new FileManager();
|
2015-07-31 08:06:21 -04:00
|
|
|
user_config = new UserConfig(); // needs file_manager
|
2014-03-29 06:33:43 -04:00
|
|
|
user_config->loadConfig();
|
2015-01-05 15:48:32 -05:00
|
|
|
// Some parts of the file manager needs user config (paths for models
|
|
|
|
// depend on artist debug flag). So init the rest of the file manager
|
|
|
|
// after reading the user config file.
|
|
|
|
file_manager->init();
|
2011-01-15 16:49:15 -05:00
|
|
|
if (UserConfigParams::m_language.toString() != "system")
|
|
|
|
{
|
2011-02-02 17:04:13 -05:00
|
|
|
#ifdef WIN32
|
2011-04-03 19:20:17 -04:00
|
|
|
std::string s=std::string("LANGUAGE=")
|
|
|
|
+UserConfigParams::m_language.c_str();
|
|
|
|
_putenv(s.c_str());
|
2011-02-02 17:04:13 -05:00
|
|
|
#else
|
2011-02-17 20:21:50 -05:00
|
|
|
setenv("LANGUAGE", UserConfigParams::m_language.c_str(), 1);
|
2011-02-02 17:04:13 -05:00
|
|
|
#endif
|
2011-01-15 16:49:15 -05:00
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-15 16:49:15 -05:00
|
|
|
translations = new Translations(); // needs file_manager
|
2010-09-29 19:09:53 -04:00
|
|
|
stk_config = new STKConfig(); // in case of --stk-config
|
|
|
|
// command line parameters
|
2009-08-27 02:22:52 -04:00
|
|
|
} // initUserConfig
|
2009-08-25 07:58:25 -04:00
|
|
|
|
|
|
|
//=============================================================================
|
2009-06-07 11:20:51 -04:00
|
|
|
void initRest()
|
|
|
|
{
|
2013-12-17 18:48:47 -05:00
|
|
|
stk_config->load(file_manager->getAsset("stk_config.xml"));
|
2010-09-29 19:09:53 -04:00
|
|
|
|
2015-01-05 15:48:32 -05:00
|
|
|
irr_driver = new IrrDriver();
|
2015-03-27 10:30:42 -04:00
|
|
|
StkTime::init(); // grabs the timer object from the irrlicht device
|
2015-01-05 15:48:32 -05:00
|
|
|
|
2011-10-12 07:28:35 -04:00
|
|
|
// Now create the actual non-null device in the irrlicht driver
|
|
|
|
irr_driver->initDevice();
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-09-11 14:17:17 -04:00
|
|
|
// Init GUI
|
|
|
|
IrrlichtDevice* device = irr_driver->getDevice();
|
|
|
|
video::IVideoDriver* driver = device->getVideoDriver();
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2011-01-10 11:49:34 -05:00
|
|
|
if (UserConfigParams::m_gamepad_visualisation)
|
|
|
|
{
|
|
|
|
gamepadVisualisation();
|
|
|
|
exit(0);
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-09-11 14:17:17 -04:00
|
|
|
GUIEngine::init(device, driver, StateManager::get());
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2010-12-28 17:48:44 -05:00
|
|
|
// This only initialises the non-network part of the addons manager. The
|
|
|
|
// online section of the addons manager will be initialised from a
|
|
|
|
// separate thread running in network http.
|
|
|
|
addons_manager = new AddonsManager();
|
2014-02-26 00:34:46 -05:00
|
|
|
Online::ProfileManager::create();
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-04-08 18:33:42 -04:00
|
|
|
// The request manager will start the login process in case of a saved
|
|
|
|
// session, so we need to read the main data from the players.xml file.
|
|
|
|
// The rest will be read later (since the rest needs the unlock- and
|
|
|
|
// achievement managers to be created, which can only be created later).
|
|
|
|
PlayerManager::create();
|
2014-01-13 00:21:48 -05:00
|
|
|
Online::RequestManager::get()->startNetworkThread();
|
2014-01-12 06:20:32 -05:00
|
|
|
NewsManager::get(); // this will create the news manager
|
2012-09-20 01:51:19 -04:00
|
|
|
|
2015-02-08 19:15:48 -05:00
|
|
|
music_manager = new MusicManager();
|
2014-09-17 07:38:21 -04:00
|
|
|
SFXManager::create();
|
2007-05-27 12:01:53 -04:00
|
|
|
// The order here can be important, e.g. KartPropertiesManager needs
|
2009-08-27 02:22:52 -04:00
|
|
|
// defaultKartProperties, which are defined in stk_config.
|
2007-05-27 12:01:53 -04:00
|
|
|
history = new History ();
|
2012-02-28 17:33:49 -05:00
|
|
|
ReplayRecorder::create();
|
2007-05-27 12:01:53 -04:00
|
|
|
material_manager = new MaterialManager ();
|
|
|
|
track_manager = new TrackManager ();
|
|
|
|
kart_properties_manager = new KartPropertiesManager();
|
|
|
|
projectile_manager = new ProjectileManager ();
|
2009-03-31 20:55:20 -04:00
|
|
|
powerup_manager = new PowerupManager ();
|
2007-05-27 12:01:53 -04:00
|
|
|
attachment_manager = new AttachmentManager ();
|
|
|
|
highscore_manager = new HighscoreManager ();
|
2015-03-25 20:28:22 -04:00
|
|
|
|
|
|
|
// The maximum texture size can not be set earlier, since
|
|
|
|
// e.g. the background image needs to be loaded in high res.
|
|
|
|
irr_driver->setMaxTextureSize();
|
2010-12-28 17:48:44 -05:00
|
|
|
KartPropertiesManager::addKartSearchDir(
|
2013-01-21 00:37:33 -05:00
|
|
|
file_manager->getAddonsFile("karts/"));
|
2010-12-31 00:04:59 -05:00
|
|
|
track_manager->addTrackSearchDir(
|
2013-01-21 00:37:33 -05:00
|
|
|
file_manager->getAddonsFile("tracks/"));
|
2011-05-26 21:06:31 -04:00
|
|
|
|
2015-07-11 09:38:52 -04:00
|
|
|
{
|
|
|
|
XMLNode characteristicsNode(file_manager->getAsset("kart_characteristics.xml"));
|
|
|
|
kart_properties_manager->loadCharacteristics(&characteristicsNode);
|
|
|
|
}
|
|
|
|
|
2008-03-14 05:49:17 -04:00
|
|
|
track_manager->loadTrackList();
|
2010-04-21 13:24:02 -04:00
|
|
|
music_manager->addMusicToTracks();
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
|
2014-03-29 06:33:43 -04:00
|
|
|
GUIEngine::addLoadingIcon(irr_driver->getTexture(FileManager::GUI,
|
2013-12-18 17:29:08 -05:00
|
|
|
"notes.png" ) );
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2010-09-20 13:36:12 -04:00
|
|
|
grand_prix_manager = new GrandPrixManager ();
|
|
|
|
// Consistency check for challenges, and enable all challenges
|
|
|
|
// that have all prerequisites fulfilled
|
|
|
|
grand_prix_manager->checkConsistency();
|
2013-12-18 17:29:08 -05:00
|
|
|
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
|
|
|
|
"cup_gold.png" ) );
|
2010-12-31 00:04:59 -05:00
|
|
|
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
race_manager = new RaceManager ();
|
2007-08-17 12:56:31 -04:00
|
|
|
// default settings for Quickstart
|
2016-01-08 01:03:50 -05:00
|
|
|
race_manager->setNumPlayers(1);
|
2007-08-17 12:56:31 -04:00
|
|
|
race_manager->setNumLaps (3);
|
2008-09-21 20:55:27 -04:00
|
|
|
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
|
2009-12-22 16:57:15 -05:00
|
|
|
race_manager->setMinorMode (RaceManager::MINOR_MODE_NORMAL_RACE);
|
2011-10-05 00:15:19 -04:00
|
|
|
race_manager->setDifficulty(
|
|
|
|
(RaceManager::Difficulty)(int)UserConfigParams::m_difficulty);
|
2014-12-12 13:54:30 -05:00
|
|
|
|
|
|
|
if (!track_manager->getTrack(UserConfigParams::m_last_track))
|
|
|
|
UserConfigParams::m_last_track.revertToDefaults();
|
2015-01-22 10:56:30 -05:00
|
|
|
|
2014-12-12 13:54:30 -05:00
|
|
|
race_manager->setTrack(UserConfigParams::m_last_track);
|
2008-09-17 23:24:19 -04:00
|
|
|
|
2010-09-29 19:09:53 -04:00
|
|
|
} // initRest
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
//=============================================================================
|
2014-03-06 01:06:41 -05:00
|
|
|
void askForInternetPermission()
|
2012-01-12 00:43:14 -05:00
|
|
|
{
|
2015-01-13 01:04:08 -05:00
|
|
|
if (UserConfigParams::m_internet_status !=
|
2014-03-06 01:06:41 -05:00
|
|
|
Online::RequestManager::IPERM_NOT_ASKED)
|
2015-01-13 01:04:08 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
class ConfirmServer :
|
|
|
|
public MessageDialog::IConfirmDialogListener
|
2014-03-06 01:06:41 -05:00
|
|
|
{
|
2015-01-13 01:04:08 -05:00
|
|
|
public:
|
|
|
|
virtual void onConfirm()
|
2014-03-06 01:06:41 -05:00
|
|
|
{
|
2015-01-13 01:04:08 -05:00
|
|
|
// Typically internet is disabled here (just better safe
|
|
|
|
// than sorry). If internet should be allowed, the news
|
|
|
|
// manager needs to be started (which in turn activates
|
|
|
|
// the addons manager).
|
|
|
|
bool need_to_start_news_manager =
|
|
|
|
UserConfigParams::m_internet_status !=
|
|
|
|
Online::RequestManager::IPERM_ALLOWED;
|
|
|
|
UserConfigParams::m_internet_status =
|
|
|
|
Online::RequestManager::IPERM_ALLOWED;
|
|
|
|
if (need_to_start_news_manager)
|
|
|
|
NewsManager::get()->init(false);
|
|
|
|
GUIEngine::ModalDialog::dismiss();
|
|
|
|
} // onConfirm
|
|
|
|
// --------------------------------------------------------
|
|
|
|
virtual void onCancel()
|
|
|
|
{
|
|
|
|
UserConfigParams::m_internet_status =
|
|
|
|
Online::RequestManager::IPERM_NOT_ALLOWED;
|
|
|
|
GUIEngine::ModalDialog::dismiss();
|
|
|
|
} // onCancel
|
|
|
|
}; // ConfirmServer
|
|
|
|
|
2015-01-22 10:56:30 -05:00
|
|
|
GUIEngine::ModalDialog *dialog =
|
2015-01-13 01:04:08 -05:00
|
|
|
new MessageDialog(_("SuperTuxKart may connect to a server "
|
|
|
|
"to download add-ons and notify you of updates. We also collect "
|
|
|
|
"anonymous hardware statistics to help with the development of STK. "
|
2015-03-11 19:33:42 -04:00
|
|
|
"Please read our privacy policy at http://privacy.supertuxkart.net. "
|
2015-01-13 01:04:08 -05:00
|
|
|
"Would you like this feature to be enabled? (To change this setting "
|
|
|
|
"at a later time, go to options, select tab "
|
|
|
|
"'User Interface', and edit \"Connect to the "
|
|
|
|
"Internet\" and \"Send anonymous HW statistics\")."),
|
|
|
|
MessageDialog::MESSAGE_DIALOG_YESNO,
|
2015-06-23 18:46:36 -04:00
|
|
|
new ConfirmServer(), true, true, 0.7f, 0.7f);
|
2015-01-18 18:21:41 -05:00
|
|
|
GUIEngine::DialogQueue::get()->pushDialog(dialog, false);
|
2014-03-06 01:06:41 -05:00
|
|
|
} // askForInternetPermission
|
|
|
|
|
|
|
|
//=============================================================================
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2014-08-22 14:40:22 -04:00
|
|
|
#if defined(WIN32) && defined(_MSC_VER)
|
|
|
|
#ifdef DEBUG
|
|
|
|
#pragma comment(linker, "/SUBSYSTEM:console")
|
|
|
|
#else
|
|
|
|
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
|
|
|
|
#endif
|
2013-05-10 19:19:36 -04:00
|
|
|
#endif
|
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2010-12-31 00:04:59 -05:00
|
|
|
int main(int argc, char *argv[] )
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2014-01-06 07:23:16 -05:00
|
|
|
CommandLine::init(argc, argv);
|
|
|
|
|
2013-12-01 23:27:55 -05:00
|
|
|
CrashReporting::installHandlers();
|
|
|
|
|
2010-12-18 20:55:29 -05:00
|
|
|
srand(( unsigned ) time( 0 ));
|
2013-04-30 03:17:02 -04:00
|
|
|
|
2014-03-29 06:33:43 -04:00
|
|
|
try
|
2014-01-06 07:23:16 -05:00
|
|
|
{
|
|
|
|
std::string s;
|
2015-04-23 14:08:19 -04:00
|
|
|
|
|
|
|
handleCmdLineOutputModifier();
|
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
if(CommandLine::has("--root", &s))
|
|
|
|
FileManager::addRootDirs(s);
|
2015-10-21 20:51:18 -04:00
|
|
|
if (CommandLine::has("--stdout", &s))
|
|
|
|
FileManager::setStdoutName(s);
|
2014-01-06 07:23:16 -05:00
|
|
|
|
2009-08-27 02:22:52 -04:00
|
|
|
// Init the minimum managers so that user config exists, then
|
|
|
|
// handle all command line options that do not need (or must
|
|
|
|
// not have) other managers initialised:
|
2014-03-29 06:33:43 -04:00
|
|
|
initUserConfig();
|
2013-04-30 03:17:02 -04:00
|
|
|
|
2014-01-06 07:23:16 -05:00
|
|
|
handleCmdLinePreliminary();
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2009-06-07 11:20:51 -04:00
|
|
|
initRest();
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2009-03-23 10:55:23 -04:00
|
|
|
input_manager = new InputManager ();
|
2013-04-30 03:17:02 -04:00
|
|
|
|
2012-01-01 16:19:13 -05:00
|
|
|
#ifdef ENABLE_WIIUSE
|
|
|
|
wiimote_manager = new WiimoteManager();
|
|
|
|
#endif
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2009-03-23 10:55:23 -04:00
|
|
|
// Get into menu mode initially.
|
2010-12-31 00:04:59 -05:00
|
|
|
input_manager->setMode(InputManager::MENU);
|
2008-09-15 00:34:46 -04:00
|
|
|
main_loop = new MainLoop();
|
2014-10-04 09:32:54 -04:00
|
|
|
material_manager->loadMaterial();
|
|
|
|
|
2013-12-18 17:29:08 -05:00
|
|
|
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
|
|
|
|
"options_video.png"));
|
2009-08-27 02:22:52 -04:00
|
|
|
kart_properties_manager -> loadAllKarts ();
|
2013-12-01 23:27:55 -05:00
|
|
|
handleXmasMode();
|
2015-02-20 19:19:15 -05:00
|
|
|
handleEasterEarMode();
|
2014-02-09 07:22:45 -05:00
|
|
|
|
|
|
|
// Needs the kart and track directories to load potential challenges
|
2014-04-08 18:33:42 -04:00
|
|
|
// in those dirs, so it can only be created after reading tracks
|
|
|
|
// and karts.
|
2014-02-09 07:22:45 -05:00
|
|
|
unlock_manager = new UnlockManager();
|
2014-02-20 06:04:03 -05:00
|
|
|
AchievementsManager::create();
|
|
|
|
|
2014-04-08 18:33:42 -04:00
|
|
|
// Reading the rest of the player data needs the unlock manager to
|
|
|
|
// initialise the game slots of all players and the AchievementsManager
|
|
|
|
// to initialise the AchievementsStatus, so it is done only now.
|
2014-04-14 19:06:50 -04:00
|
|
|
PlayerManager::get()->initRemainingData();
|
2014-02-09 07:22:45 -05:00
|
|
|
|
2014-03-29 06:33:43 -04:00
|
|
|
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
|
2013-12-18 17:29:08 -05:00
|
|
|
"gui_lock.png" ) );
|
2014-02-09 07:22:45 -05:00
|
|
|
projectile_manager->loadData();
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2010-04-23 08:54:15 -04:00
|
|
|
// Both item_manager and powerup_manager load models and therefore
|
2013-05-29 18:04:35 -04:00
|
|
|
// textures from the model directory. To avoid reading the
|
2010-04-23 08:54:15 -04:00
|
|
|
// materials.xml twice, we do this here once for both:
|
2013-12-17 18:48:47 -05:00
|
|
|
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""));
|
2013-05-29 18:04:35 -04:00
|
|
|
const std::string materials_file =
|
2013-12-17 18:48:47 -05:00
|
|
|
file_manager->getAsset(FileManager::MODEL,"materials.xml");
|
2010-04-23 08:54:15 -04:00
|
|
|
if(materials_file!="")
|
|
|
|
{
|
2011-05-03 20:15:46 -04:00
|
|
|
// Some of the materials might be needed later, so just add
|
|
|
|
// them all permanently (i.e. as shared). Adding them temporary
|
|
|
|
// will actually not be possible: powerup_manager adds some
|
|
|
|
// permanent icon materials, which would (with the current
|
|
|
|
// implementation) make the temporary materials permanent anyway.
|
|
|
|
material_manager->addSharedMaterial(materials_file);
|
2010-04-23 08:54:15 -04:00
|
|
|
}
|
2011-09-13 20:48:49 -04:00
|
|
|
Referee::init();
|
2015-02-08 19:15:48 -05:00
|
|
|
powerup_manager->loadAllPowerups();
|
2012-08-09 02:37:29 -04:00
|
|
|
ItemManager::loadDefaultItemMeshes();
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2013-12-18 17:29:08 -05:00
|
|
|
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
|
|
|
|
"gift.png") );
|
2010-09-18 19:09:02 -04:00
|
|
|
|
2010-04-23 08:54:15 -04:00
|
|
|
file_manager->popTextureSearchPath();
|
|
|
|
|
2014-02-09 07:22:45 -05:00
|
|
|
attachment_manager->loadModels();
|
2007-12-24 22:23:32 -05:00
|
|
|
|
2013-12-18 17:29:08 -05:00
|
|
|
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
|
|
|
|
"banana.png") );
|
2010-09-18 19:09:02 -04:00
|
|
|
|
2009-08-27 02:22:52 -04:00
|
|
|
//handleCmdLine() needs InitTuxkart() so it can't be called first
|
2014-01-06 07:23:16 -05:00
|
|
|
if(!handleCmdLine()) exit(0);
|
2009-08-27 02:22:52 -04:00
|
|
|
|
2011-10-13 17:29:10 -04:00
|
|
|
addons_manager->checkInstalledAddons();
|
2012-10-13 15:49:48 -04:00
|
|
|
|
|
|
|
// Load addons.xml to get info about addons even when not
|
|
|
|
// allowed to access the internet
|
2014-03-29 06:33:43 -04:00
|
|
|
if (UserConfigParams::m_internet_status !=
|
2014-01-13 00:21:48 -05:00
|
|
|
Online::RequestManager::IPERM_ALLOWED)
|
|
|
|
{
|
2014-03-30 11:48:38 -04:00
|
|
|
std::string xml_file = file_manager->getAddonsFile("addonsX.xml");
|
|
|
|
if (file_manager->fileExists(xml_file))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
const XMLNode *xml = new XMLNode(xml_file);
|
|
|
|
addons_manager->initAddons(xml);
|
|
|
|
}
|
|
|
|
catch (std::runtime_error& e)
|
|
|
|
{
|
|
|
|
Log::warn("Addons", "Exception thrown when initializing addons manager : %s", e.what());
|
|
|
|
}
|
2012-10-13 15:49:48 -04:00
|
|
|
}
|
|
|
|
}
|
2014-02-09 16:41:54 -05:00
|
|
|
|
2015-01-07 18:05:19 -05:00
|
|
|
if(UserConfigParams::m_unit_testing)
|
|
|
|
{
|
2015-02-20 19:19:15 -05:00
|
|
|
runUnitTests();
|
2015-01-07 18:05:19 -05:00
|
|
|
exit(0);
|
|
|
|
}
|
2015-01-06 01:09:16 -05:00
|
|
|
|
2015-03-26 20:53:25 -04:00
|
|
|
if (!ProfileWorld::isNoGraphics() &&
|
|
|
|
GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_DRIVER_RECENT_ENOUGH))
|
2015-01-18 18:21:41 -05:00
|
|
|
{
|
2015-03-26 20:53:25 -04:00
|
|
|
if (UserConfigParams::m_old_driver_popup)
|
2015-03-25 13:53:09 -04:00
|
|
|
{
|
|
|
|
MessageDialog *dialog =
|
|
|
|
new MessageDialog(_("Your driver version is too old. Please install "
|
|
|
|
"the latest video drivers."),
|
|
|
|
/*from queue*/ true);
|
|
|
|
GUIEngine::DialogQueue::get()->pushDialog(dialog);
|
|
|
|
}
|
2015-03-26 20:53:25 -04:00
|
|
|
Log::warn("OpenGL", "Driver is too old!");
|
|
|
|
}
|
|
|
|
else if (!CVS->isGLSL())
|
|
|
|
{
|
|
|
|
if (UserConfigParams::m_old_driver_popup)
|
2015-03-25 13:53:09 -04:00
|
|
|
{
|
|
|
|
MessageDialog *dialog =
|
|
|
|
new MessageDialog(_("Your OpenGL version appears to be too old. Please verify "
|
|
|
|
"if an update for your video driver is available. SuperTuxKart requires OpenGL 3.1 or better."),
|
|
|
|
/*from queue*/ true);
|
|
|
|
GUIEngine::DialogQueue::get()->pushDialog(dialog);
|
|
|
|
}
|
2015-03-26 20:53:25 -04:00
|
|
|
Log::warn("OpenGL", "OpenGL version is too old!");
|
2015-03-11 20:28:35 -04:00
|
|
|
}
|
2015-01-18 18:21:41 -05:00
|
|
|
|
2014-10-21 17:20:26 -04:00
|
|
|
// Note that on the very first run of STK internet status is set to
|
|
|
|
// "not asked", so the report will only be sent in the next run.
|
2014-09-16 08:02:20 -04:00
|
|
|
if(UserConfigParams::m_internet_status==Online::RequestManager::IPERM_ALLOWED)
|
|
|
|
{
|
|
|
|
HardwareStats::reportHardwareStats();
|
|
|
|
}
|
|
|
|
|
2014-02-09 16:41:54 -05:00
|
|
|
if(!UserConfigParams::m_no_start_screen)
|
2009-08-14 13:05:52 -04:00
|
|
|
{
|
2014-05-15 18:24:15 -04:00
|
|
|
// If there is a current player, it was saved in the config file,
|
2014-05-27 01:36:44 -04:00
|
|
|
// so we immediately start the main menu (unless it was requested
|
|
|
|
// to always show the login screen). Otherwise show the login
|
2014-05-15 18:24:15 -04:00
|
|
|
// screen first.
|
2014-05-27 01:36:44 -04:00
|
|
|
if(PlayerManager::getCurrentPlayer() && !
|
|
|
|
UserConfigParams::m_always_show_login_screen)
|
|
|
|
{
|
2014-09-23 02:43:50 -04:00
|
|
|
MainMenuScreen::getInstance()->push();
|
2014-05-27 01:36:44 -04:00
|
|
|
}
|
2014-05-15 18:24:15 -04:00
|
|
|
else
|
2014-05-16 21:43:05 -04:00
|
|
|
{
|
2014-09-23 02:43:50 -04:00
|
|
|
UserScreen::getInstance()->push();
|
2014-05-16 21:43:05 -04:00
|
|
|
// If there is no player, push the RegisterScreen on top of
|
|
|
|
// the login screen. This way on first start players are
|
|
|
|
// forced to create a player.
|
2015-01-13 01:07:29 -05:00
|
|
|
if (PlayerManager::get()->getNumPlayers() == 0)
|
|
|
|
{
|
2014-09-23 02:43:50 -04:00
|
|
|
RegisterScreen::getInstance()->push();
|
2015-01-13 01:07:29 -05:00
|
|
|
RegisterScreen::getInstance()->setParent(UserScreen::getInstance());
|
|
|
|
}
|
2014-05-16 21:43:05 -04:00
|
|
|
}
|
2013-02-05 06:11:25 -05:00
|
|
|
#ifdef ENABLE_WIIUSE
|
|
|
|
// Show a dialog to allow connection of wiimotes. */
|
|
|
|
if(WiimoteManager::isEnabled())
|
|
|
|
{
|
|
|
|
wiimote_manager->askUserToConnectWiimotes();
|
|
|
|
}
|
|
|
|
#endif
|
2014-03-06 01:06:41 -05:00
|
|
|
askForInternetPermission();
|
2009-08-14 13:05:52 -04:00
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
else
|
2009-08-14 13:05:52 -04:00
|
|
|
{
|
2014-04-27 17:51:24 -04:00
|
|
|
setupRaceStart();
|
2009-08-14 13:05:52 -04:00
|
|
|
// Go straight to the race
|
|
|
|
StateManager::get()->enterGameState();
|
|
|
|
}
|
2013-01-09 00:46:26 -05:00
|
|
|
|
|
|
|
// If an important news message exists it is shown in a popup dialog.
|
2013-05-29 18:04:35 -04:00
|
|
|
const core::stringw important_message =
|
2014-01-12 06:20:32 -05:00
|
|
|
NewsManager::get()->getImportantMessage();
|
2013-01-09 00:46:26 -05:00
|
|
|
if(important_message!="")
|
|
|
|
{
|
|
|
|
new MessageDialog(important_message,
|
|
|
|
MessageDialog::MESSAGE_DIALOG_OK,
|
|
|
|
NULL, true);
|
|
|
|
} // if important_message
|
|
|
|
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
// Replay a race
|
|
|
|
// =============
|
2008-10-06 09:40:11 -04:00
|
|
|
if(history->replayHistory())
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
// This will setup the race manager etc.
|
|
|
|
history->Load();
|
2013-07-05 08:01:29 -04:00
|
|
|
race_manager->setupPlayerKartInfo();
|
2012-04-01 11:42:44 -04:00
|
|
|
race_manager->startNew(false);
|
2008-09-15 00:34:46 -04:00
|
|
|
main_loop->run();
|
2007-05-27 12:01:53 -04:00
|
|
|
// well, actually run() will never return, since
|
|
|
|
// it exits after replaying history (see history::GetNextDT()).
|
|
|
|
// So the next line is just to make this obvious here!
|
|
|
|
exit(-3);
|
|
|
|
}
|
2008-09-07 09:14:14 -04:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
// Not replaying
|
|
|
|
// =============
|
2009-08-23 11:42:58 -04:00
|
|
|
if(!ProfileWorld::isProfileMode())
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2009-06-20 21:10:43 -04:00
|
|
|
if(UserConfigParams::m_no_start_screen)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
// Quickstart (-N)
|
|
|
|
// ===============
|
2007-08-17 12:56:31 -04:00
|
|
|
// all defaults are set in InitTuxkart()
|
2013-07-05 08:01:29 -04:00
|
|
|
race_manager->setupPlayerKartInfo();
|
2012-04-01 11:42:44 -04:00
|
|
|
race_manager->startNew(false);
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
}
|
2008-02-17 07:58:12 -05:00
|
|
|
else // profile
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
// Profiling
|
|
|
|
// =========
|
2008-09-21 20:55:27 -04:00
|
|
|
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
|
2013-07-05 08:01:29 -04:00
|
|
|
race_manager->setupPlayerKartInfo();
|
2012-04-01 11:42:44 -04:00
|
|
|
race_manager->startNew(false);
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2008-09-15 00:34:46 -04:00
|
|
|
main_loop->run();
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
} // try
|
|
|
|
catch (std::exception &e)
|
|
|
|
{
|
2013-03-14 01:26:17 -04:00
|
|
|
Log::error("main", "Exception caught : %s.",e.what());
|
|
|
|
Log::error("main", "Aborting SuperTuxKart.");
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
|
2007-12-24 22:23:32 -05:00
|
|
|
/* Program closing...*/
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2012-01-01 16:19:13 -05:00
|
|
|
#ifdef ENABLE_WIIUSE
|
|
|
|
if(wiimote_manager)
|
|
|
|
delete wiimote_manager;
|
|
|
|
#endif
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2013-06-21 04:19:17 -04:00
|
|
|
// If the window was closed in the middle of a race, remove players,
|
|
|
|
// so we don't crash later when StateManager tries to access input devices.
|
|
|
|
StateManager::get()->resetActivePlayers();
|
2011-10-05 00:15:19 -04:00
|
|
|
if(input_manager) delete input_manager; // if early crash avoid delete NULL
|
2015-11-01 05:28:39 -05:00
|
|
|
|
2015-11-20 20:20:05 -05:00
|
|
|
if(NetworkConfig::get()->isNetworking() && STKHost::existHost())
|
2015-11-01 05:28:39 -05:00
|
|
|
STKHost::get()->abort();
|
2010-12-31 00:04:59 -05:00
|
|
|
|
2011-08-15 17:59:57 -04:00
|
|
|
cleanSuperTuxKart();
|
2008-11-07 15:42:24 -05:00
|
|
|
|
2011-09-22 14:08:04 -04:00
|
|
|
#ifdef DEBUG
|
|
|
|
MemoryLeaks::checkForLeaks();
|
|
|
|
#endif
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2013-12-01 23:27:55 -05:00
|
|
|
#ifndef WIN32
|
|
|
|
if (user_config) //close logfiles
|
|
|
|
{
|
|
|
|
Log::closeOutputFiles();
|
|
|
|
#endif
|
|
|
|
fclose(stderr);
|
|
|
|
fclose(stdout);
|
|
|
|
#ifndef WIN32
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-01-05 15:48:32 -05:00
|
|
|
delete file_manager;
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
return 0 ;
|
2013-05-31 02:26:47 -04:00
|
|
|
} // main
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2014-02-09 07:22:45 -05:00
|
|
|
// ============================================================================
|
2013-04-21 08:39:25 -04:00
|
|
|
#ifdef WIN32
|
|
|
|
//routine for running under windows
|
2014-03-29 06:33:43 -04:00
|
|
|
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
2014-02-09 07:22:45 -05:00
|
|
|
LPTSTR lpCmdLine, int nCmdShow)
|
2013-04-21 08:39:25 -04:00
|
|
|
{
|
|
|
|
return main(__argc, __argv);
|
|
|
|
}
|
|
|
|
#endif
|
2014-02-09 07:22:45 -05:00
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/** Frees all manager and their associated memory.
|
|
|
|
*/
|
|
|
|
static void cleanSuperTuxKart()
|
|
|
|
{
|
|
|
|
|
|
|
|
delete main_loop;
|
|
|
|
|
|
|
|
if(Online::RequestManager::isRunning())
|
|
|
|
Online::RequestManager::get()->stopNetworkThread();
|
2015-02-03 00:27:05 -05:00
|
|
|
|
|
|
|
// Stop music (this request will go into the sfx manager queue, so it needs
|
|
|
|
// to be done before stopping the thread).
|
|
|
|
music_manager->stopMusic();
|
2014-09-22 03:04:14 -04:00
|
|
|
SFXManager::get()->stopThread();
|
2014-06-04 02:51:29 -04:00
|
|
|
irr_driver->updateConfigIfRelevant();
|
|
|
|
AchievementsManager::destroy();
|
|
|
|
Referee::cleanup();
|
2014-06-04 17:56:51 -04:00
|
|
|
if(ReplayPlay::get()) ReplayPlay::destroy();
|
|
|
|
if(race_manager) delete race_manager;
|
2014-02-09 07:22:45 -05:00
|
|
|
if(grand_prix_manager) delete grand_prix_manager;
|
|
|
|
if(highscore_manager) delete highscore_manager;
|
|
|
|
if(attachment_manager) delete attachment_manager;
|
|
|
|
ItemManager::removeTextures();
|
|
|
|
if(powerup_manager) delete powerup_manager;
|
|
|
|
if(projectile_manager) delete projectile_manager;
|
|
|
|
if(kart_properties_manager) delete kart_properties_manager;
|
|
|
|
if(track_manager) delete track_manager;
|
|
|
|
if(material_manager) delete material_manager;
|
|
|
|
if(history) delete history;
|
|
|
|
ReplayRecorder::destroy();
|
|
|
|
delete ParticleKindManager::get();
|
|
|
|
PlayerManager::destroy();
|
|
|
|
if(unlock_manager) delete unlock_manager;
|
2014-06-04 17:56:51 -04:00
|
|
|
Online::ProfileManager::destroy();
|
|
|
|
GUIEngine::DialogQueue::deallocate();
|
|
|
|
|
|
|
|
// Now finish shutting down objects which a separate thread. The
|
|
|
|
// RequestManager has been signaled to shut down as early as possible,
|
|
|
|
// the NewsManager thread should have finished quite early on anyway.
|
|
|
|
// But still give them some additional time to finish. It avoids a
|
|
|
|
// race condition where a thread might access the file manager after it
|
|
|
|
// was deleted (in cleanUserConfig below), but before STK finishes and
|
|
|
|
// the os takes all threads down.
|
2014-04-19 13:44:30 -04:00
|
|
|
|
2014-06-04 02:51:29 -04:00
|
|
|
if(!NewsManager::get()->waitForReadyToDeleted(2.0f))
|
|
|
|
{
|
2014-06-04 17:56:51 -04:00
|
|
|
Log::info("Thread", "News manager not stopping, exiting anyway.");
|
2014-06-04 02:51:29 -04:00
|
|
|
}
|
|
|
|
NewsManager::deallocate();
|
2014-06-04 17:56:51 -04:00
|
|
|
|
|
|
|
if(!Online::RequestManager::get()->waitForReadyToDeleted(5.0f))
|
|
|
|
{
|
|
|
|
Log::info("Thread", "Request Manager not aborting in time, aborting.");
|
|
|
|
}
|
|
|
|
Online::RequestManager::deallocate();
|
|
|
|
|
2015-02-03 00:27:05 -05:00
|
|
|
if (!SFXManager::get()->waitForReadyToDeleted(2.0f))
|
|
|
|
{
|
|
|
|
Log::info("Thread", "SFXManager not stopping, exiting anyway.");
|
|
|
|
}
|
|
|
|
SFXManager::destroy();
|
|
|
|
|
|
|
|
// Music manager can not be deleted before the sfx thread is stopped
|
2015-02-04 01:08:22 -05:00
|
|
|
// (since sfx commands can contain music information, which are
|
|
|
|
// deleted by the music manager).
|
2015-02-03 00:27:05 -05:00
|
|
|
delete music_manager;
|
|
|
|
|
2014-08-18 08:42:27 -04:00
|
|
|
// The addons manager might still be called from a currenty running request
|
|
|
|
// in the request manager, so it can not be deleted earlier.
|
|
|
|
if(addons_manager) delete addons_manager;
|
|
|
|
|
2014-06-04 17:56:51 -04:00
|
|
|
// FIXME: do we need to wait for threads there, can they be
|
|
|
|
// moved further up?
|
2015-11-12 01:52:04 -05:00
|
|
|
ServersManager::deallocate();
|
2015-11-20 20:20:05 -05:00
|
|
|
if(NetworkConfig::get()->isNetworking() && STKHost::existHost())
|
2015-11-01 05:28:39 -05:00
|
|
|
STKHost::destroy();
|
2014-06-04 17:56:51 -04:00
|
|
|
|
2014-04-19 13:44:30 -04:00
|
|
|
cleanUserConfig();
|
2014-02-09 07:22:45 -05:00
|
|
|
|
|
|
|
StateManager::deallocate();
|
|
|
|
GUIEngine::EventHandler::deallocate();
|
|
|
|
} // cleanSuperTuxKart
|
|
|
|
|
2014-04-19 13:44:30 -04:00
|
|
|
//=============================================================================
|
|
|
|
/**
|
|
|
|
* Frees all the memory of initUserConfig()
|
|
|
|
*/
|
|
|
|
static void cleanUserConfig()
|
|
|
|
{
|
|
|
|
if(stk_config) delete stk_config;
|
|
|
|
if(translations) delete translations;
|
2014-06-04 02:51:29 -04:00
|
|
|
if (user_config)
|
|
|
|
{
|
|
|
|
// In case that abort is triggered before user_config exists
|
|
|
|
if (UserConfigParams::m_crashed) UserConfigParams::m_crashed = false;
|
|
|
|
user_config->saveConfig();
|
|
|
|
delete user_config;
|
|
|
|
}
|
|
|
|
|
2014-04-19 13:44:30 -04:00
|
|
|
if(irr_driver) delete irr_driver;
|
2015-01-05 15:48:32 -05:00
|
|
|
} // cleanUserConfig
|
|
|
|
|
2015-02-20 19:19:15 -05:00
|
|
|
//=============================================================================
|
|
|
|
void runUnitTests()
|
|
|
|
{
|
|
|
|
GraphicsRestrictions::unitTesting();
|
2016-02-23 00:29:57 -05:00
|
|
|
NewNetworkString::unitTesting();
|
2015-02-20 19:19:15 -05:00
|
|
|
// Test easter mode: in 2015 Easter is 5th of April - check with 0 days
|
|
|
|
// before and after
|
|
|
|
int saved_easter_mode = UserConfigParams::m_easter_ear_mode;
|
|
|
|
UserConfigParams::m_easter_ear_mode = 0; // disable always on or off mode
|
|
|
|
assert( isEasterMode( 5, 4, 2015, 0));
|
|
|
|
assert(!isEasterMode( 4, 4, 2015, 0));
|
|
|
|
assert(!isEasterMode( 6, 4, 2015, 0));
|
|
|
|
|
|
|
|
assert( isEasterMode( 1, 4, 2018, 0));
|
|
|
|
assert( isEasterMode(27, 3, 2016, 0));
|
|
|
|
|
|
|
|
// Check days before/after
|
|
|
|
assert( isEasterMode( 2, 4, 2015, 3));
|
|
|
|
assert(!isEasterMode( 1, 4, 2015, 3));
|
|
|
|
assert( isEasterMode( 8, 4, 2015, 3));
|
|
|
|
assert(!isEasterMode( 9, 4, 2015, 3));
|
|
|
|
|
|
|
|
// Check if going to previous month is handled correctly: 1/4/2018
|
|
|
|
assert( isEasterMode(27, 3, 2018, 5));
|
|
|
|
assert(!isEasterMode(26, 3, 2018, 5));
|
|
|
|
assert( isEasterMode( 6, 4, 2018, 5));
|
|
|
|
assert(!isEasterMode( 7, 4, 2018, 5));
|
|
|
|
|
|
|
|
// Check if going to previous month is handled correctly: 1/4/2018
|
|
|
|
assert( isEasterMode( 1, 4, 2016, 5));
|
|
|
|
assert(!isEasterMode( 2, 4, 2016, 5));
|
|
|
|
assert( isEasterMode(22, 3, 2016, 5));
|
|
|
|
assert(!isEasterMode(21, 3, 2016, 5));
|
|
|
|
UserConfigParams::m_easter_ear_mode = saved_easter_mode;
|
2016-02-23 00:29:57 -05:00
|
|
|
} // runUnitTests
|