/*************************************************************************/ /* main.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "main.h" #include "core/config/project_settings.h" #include "core/core_globals.h" #include "core/core_string_names.h" #include "core/crypto/crypto.h" #include "core/debugger/engine_debugger.h" #include "core/extension/extension_api_dump.h" #include "core/extension/native_extension_manager.h" #include "core/input/input.h" #include "core/input/input_map.h" #include "core/io/dir_access.h" #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" #include "core/io/file_access_zip.h" #include "core/io/image_loader.h" #include "core/io/ip.h" #include "core/io/resource_loader.h" #include "core/object/message_queue.h" #include "core/os/os.h" #include "core/os/time.h" #include "core/register_core_types.h" #include "core/string/translation.h" #include "core/version.h" #include "drivers/register_driver_types.h" #include "main/app_icon.gen.h" #include "main/main_timer_sync.h" #include "main/performance.h" #include "main/splash.gen.h" #include "modules/register_module_types.h" #include "platform/register_platform_apis.h" #include "scene/main/scene_tree.h" #include "scene/main/window.h" #include "scene/register_scene_types.h" #include "scene/resources/packed_scene.h" #include "servers/audio_server.h" #include "servers/camera_server.h" #include "servers/display_server.h" #include "servers/movie_writer/movie_writer.h" #include "servers/movie_writer/movie_writer_mjpeg.h" #include "servers/navigation_server_2d.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" #include "servers/physics_server_3d.h" #include "servers/register_server_types.h" #include "servers/rendering/rendering_server_default.h" #include "servers/text/text_server_dummy.h" #include "servers/text_server.h" #include "servers/xr_server.h" #ifdef TESTS_ENABLED #include "tests/test_main.h" #endif #ifdef TOOLS_ENABLED #include "editor/doc_data_class_path.gen.h" #include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_settings.h" #include "editor/editor_translation.h" #include "editor/progress_dialog.h" #include "editor/project_converter_3_to_4.h" #include "editor/project_manager.h" #ifndef NO_EDITOR_SPLASH #include "main/splash_editor.gen.h" #endif #endif #include "modules/modules_enabled.gen.h" // For mono. /* Static members */ // Singletons // Initialized in setup() static Engine *engine = nullptr; static ProjectSettings *globals = nullptr; static Input *input = nullptr; static InputMap *input_map = nullptr; static TranslationServer *translation_server = nullptr; static Performance *performance = nullptr; static PackedData *packed_data = nullptr; static Time *time_singleton = nullptr; #ifdef MINIZIP_ENABLED static ZipArchive *zip_packed_data = nullptr; #endif static FileAccessNetworkClient *file_access_network_client = nullptr; static MessageQueue *message_queue = nullptr; // Initialized in setup2() static AudioServer *audio_server = nullptr; static DisplayServer *display_server = nullptr; static RenderingServer *rendering_server = nullptr; static CameraServer *camera_server = nullptr; static XRServer *xr_server = nullptr; static TextServerManager *tsman = nullptr; static PhysicsServer3D *physics_server_3d = nullptr; static PhysicsServer2D *physics_server_2d = nullptr; static NavigationServer3D *navigation_server_3d = nullptr; static NavigationServer2D *navigation_server_2d = nullptr; // We error out if setup2() doesn't turn this true static bool _start_success = false; // Drivers String tablet_driver = ""; String text_driver = ""; String rendering_driver = ""; static int text_driver_idx = -1; static int display_driver_idx = -1; static int audio_driver_idx = -1; // Engine config/tools static bool single_window = false; static bool editor = false; static bool project_manager = false; static bool cmdline_tool = false; static String locale; static bool show_help = false; static bool auto_quit = false; static OS::ProcessID editor_pid = 0; #ifdef TOOLS_ENABLED static bool auto_build_solutions = false; static String debug_server_uri; static int converter_max_kb_file = 4 * 1024; // 4MB static int converter_max_line_length = 100000; HashMap> forwardable_cli_arguments; #endif bool use_startup_benchmark = false; String startup_benchmark_file; // Display static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED; static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE; static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED; static uint32_t window_flags = 0; static Size2i window_size = Size2i(1152, 648); static int init_screen = -1; static bool init_fullscreen = false; static bool init_maximized = false; static bool init_windowed = false; static bool init_always_on_top = false; static bool init_use_custom_pos = false; static Vector2 init_custom_pos; // Debug static bool use_debug_profiler = false; #ifdef DEBUG_ENABLED static bool debug_collisions = false; static bool debug_paths = false; static bool debug_navigation = false; #endif static int frame_delay = 0; static bool disable_render_loop = false; static int fixed_fps = -1; static MovieWriter *movie_writer = nullptr; static bool disable_vsync = false; static bool print_fps = false; #ifdef TOOLS_ENABLED static bool dump_extension_api = false; #endif bool profile_gpu = false; /* Helper methods */ bool Main::is_cmdline_tool() { return cmdline_tool; } #ifdef TOOLS_ENABLED const Vector &Main::get_forwardable_cli_arguments(Main::CLIScope p_scope) { return forwardable_cli_arguments[p_scope]; } #endif static String unescape_cmdline(const String &p_str) { return p_str.replace("%20", " "); } static String get_full_version_string() { String hash = String(VERSION_HASH); if (!hash.is_empty()) { hash = "." + hash.left(9); } return String(VERSION_FULL_BUILD) + hash; } // FIXME: Could maybe be moved to PhysicsServer3DManager and PhysicsServer2DManager directly // to have less code in main.cpp. void initialize_physics() { /// 3D Physics Server physics_server_3d = PhysicsServer3DManager::new_server( ProjectSettings::get_singleton()->get(PhysicsServer3DManager::setting_property_name)); if (!physics_server_3d) { // Physics server not found, Use the default physics physics_server_3d = PhysicsServer3DManager::new_default_server(); } ERR_FAIL_COND(!physics_server_3d); physics_server_3d->init(); /// 2D Physics server physics_server_2d = PhysicsServer2DManager::new_server( ProjectSettings::get_singleton()->get(PhysicsServer2DManager::setting_property_name)); if (!physics_server_2d) { // Physics server not found, Use the default physics physics_server_2d = PhysicsServer2DManager::new_default_server(); } ERR_FAIL_COND(!physics_server_2d); physics_server_2d->init(); } void finalize_physics() { physics_server_3d->finish(); memdelete(physics_server_3d); physics_server_2d->finish(); memdelete(physics_server_2d); } void finalize_display() { rendering_server->finish(); memdelete(rendering_server); memdelete(display_server); } void initialize_navigation_server() { ERR_FAIL_COND(navigation_server_3d != nullptr); navigation_server_3d = NavigationServer3DManager::new_default_server(); navigation_server_2d = memnew(NavigationServer2D); } void finalize_navigation_server() { memdelete(navigation_server_3d); navigation_server_3d = nullptr; memdelete(navigation_server_2d); navigation_server_2d = nullptr; } //#define DEBUG_INIT #ifdef DEBUG_INIT #define MAIN_PRINT(m_txt) print_line(m_txt) #else #define MAIN_PRINT(m_txt) #endif void Main::print_help(const char *p_binary) { print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n"); OS::get_singleton()->print("(c) 2007-2022 Juan Linietsky, Ariel Manzur.\n"); OS::get_singleton()->print("(c) 2014-2022 Godot Engine contributors.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Usage: %s [options] [path to scene or 'project.godot' file]\n", p_binary); OS::get_singleton()->print("\n"); OS::get_singleton()->print("General options:\n"); OS::get_singleton()->print(" -h, --help Display this help message.\n"); OS::get_singleton()->print(" --version Display the version string.\n"); OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n"); OS::get_singleton()->print(" -q, --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Run options:\n"); OS::get_singleton()->print(" -- Separator for user-provided arguments. Following arguments are not used by the engine, but can be read from `OS.get_cmdline_user_args()`.\n"); #ifdef TOOLS_ENABLED OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n"); OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n"); OS::get_singleton()->print(" --debug-server Start the editor debug server (://[:], e.g. tcp://127.0.0.1:6007)\n"); #endif OS::get_singleton()->print(" --quit Quit after the first iteration.\n"); OS::get_singleton()->print(" -l, --language Use a specific locale ( being a two-letter code).\n"); OS::get_singleton()->print(" --path Path to a project ( must contain a 'project.godot' file).\n"); OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n"); OS::get_singleton()->print(" --main-pack Path to a pack (.pck) file to load.\n"); OS::get_singleton()->print(" --render-thread Render thread mode ('unsafe', 'safe', 'separate').\n"); OS::get_singleton()->print(" --remote-fs
Remote filesystem ([:] address).\n"); OS::get_singleton()->print(" --remote-fs-password Password for remote filesystem.\n"); OS::get_singleton()->print(" --audio-driver Audio driver ["); for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) { if (i > 0) { OS::get_singleton()->print(", "); } OS::get_singleton()->print("'%s'", AudioDriverManager::get_driver(i)->get_name()); } OS::get_singleton()->print("].\n"); OS::get_singleton()->print(" --display-driver Display driver (and rendering driver) ["); for (int i = 0; i < DisplayServer::get_create_function_count(); i++) { if (i > 0) { OS::get_singleton()->print(", "); } OS::get_singleton()->print("'%s' (", DisplayServer::get_create_function_name(i)); Vector rd = DisplayServer::get_create_function_rendering_drivers(i); for (int j = 0; j < rd.size(); j++) { if (j > 0) { OS::get_singleton()->print(", "); } OS::get_singleton()->print("'%s'", rd[j].utf8().get_data()); } OS::get_singleton()->print(")"); } OS::get_singleton()->print("].\n"); OS::get_singleton()->print(" --rendering-driver Rendering driver (depends on display driver).\n"); OS::get_singleton()->print(" --gpu-index Use a specific GPU (run with --verbose to get available device list).\n"); OS::get_singleton()->print(" --text-driver Text driver (Fonts, BiDi, shaping)\n"); OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n"); OS::get_singleton()->print(" --headless Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script.\n"); OS::get_singleton()->print(" --write-movie Run the engine in a way that a movie is written (by default .avi MJPEG). Fixed FPS is forced when enabled, but can be used to change movie FPS. Disabling vsync can speed up movie writing but makes interaction more difficult.\n"); OS::get_singleton()->print(" --disable-vsync Force disabling of vsync. Run the engine in a way that a movie is written (by default .avi MJPEG). Fixed FPS is forced when enabled, but can be used to change movie FPS.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Display options:\n"); OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n"); OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n"); OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n"); OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n"); OS::get_singleton()->print(" --resolution x Request window resolution.\n"); OS::get_singleton()->print(" --position , Request window position.\n"); OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); OS::get_singleton()->print(" --xr-mode Select XR mode (default/off/on).\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Debug options:\n"); OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n"); OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n"); OS::get_singleton()->print(" --gpu-profile Show a GPU profile of the tasks that took the most time during frame rendering.\n"); OS::get_singleton()->print(" --gpu-validation Enable graphics API validation layers for debugging.\n"); #if DEBUG_ENABLED OS::get_singleton()->print(" --gpu-abort Abort on graphics API usage errors (usually validation layer errors). May help see the problem if your system freezes.\n"); #endif OS::get_singleton()->print(" --remote-debug Remote debug (://[:], e.g. tcp://127.0.0.1:6007).\n"); #if defined(DEBUG_ENABLED) OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n"); OS::get_singleton()->print(" --debug-paths Show path lines when running the scene.\n"); OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n"); OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n"); #endif OS::get_singleton()->print(" --frame-delay Simulate high CPU load (delay each frame by milliseconds).\n"); OS::get_singleton()->print(" --time-scale Force time scale (higher values are faster, 1.0 is normal speed).\n"); OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n"); OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n"); OS::get_singleton()->print(" --fixed-fps Force a fixed number of frames per second. This setting disables real-time synchronization.\n"); OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Standalone tools:\n"); OS::get_singleton()->print(" -s, --script