2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* main.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2017-01-01 22:01:57 +01:00
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
2017-04-08 00:11:42 +02:00
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 02:10:30 +01:00
/* */
/* 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"
2017-08-19 16:45:03 +02:00
2017-06-23 17:03:41 +02:00
# include "app_icon.gen.h"
2014-02-10 02:10:30 +01:00
# include "core/register_core_types.h"
# include "drivers/register_driver_types.h"
2017-03-05 16:44:50 +01:00
# include "message_queue.h"
2014-02-10 02:10:30 +01:00
# include "modules/register_module_types.h"
2017-03-05 16:44:50 +01:00
# include "os/os.h"
2017-11-16 01:33:48 +01:00
# include "platform/register_platform_apis.h"
2017-07-19 22:00:46 +02:00
# include "project_settings.h"
2017-03-05 16:44:50 +01:00
# include "scene/register_scene_types.h"
2014-02-10 02:10:30 +01:00
# include "script_debugger_local.h"
# include "script_debugger_remote.h"
2017-03-05 16:44:50 +01:00
# include "servers/register_server_types.h"
2017-06-23 17:03:41 +02:00
# include "splash.gen.h"
2017-01-26 01:55:59 +01:00
2014-02-10 02:10:30 +01:00
# include "input_map.h"
# include "io/resource_loader.h"
2017-06-27 03:58:03 +02:00
# include "scene/main/scene_tree.h"
2017-10-07 15:51:17 +02:00
# include "servers/arvr_server.h"
2017-01-15 20:06:14 +01:00
# include "servers/audio_server.h"
2017-10-21 13:02:06 +02:00
# include "servers/physics_2d_server.h"
# include "servers/physics_server.h"
2014-10-07 06:31:49 +02:00
2014-02-10 02:10:30 +01:00
# include "io/resource_loader.h"
2017-03-05 16:44:50 +01:00
# include "script_language.h"
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
# include "core/io/ip.h"
2017-01-08 21:33:23 +01:00
# include "main/tests/test_main.h"
2014-02-10 02:10:30 +01:00
# include "os/dir_access.h"
# include "scene/main/viewport.h"
2017-03-05 16:44:50 +01:00
# include "scene/resources/packed_scene.h"
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
2017-03-05 14:21:25 +01:00
# include "editor/doc/doc_data.h"
2017-09-13 09:13:23 +02:00
# include "editor/doc/doc_data_class_path.gen.h"
2017-03-05 14:21:25 +01:00
# include "editor/editor_node.h"
# include "editor/project_manager.h"
2014-02-10 02:10:30 +01:00
# endif
# include "io/file_access_network.h"
# include "servers/physics_2d_server.h"
# include "core/io/file_access_pack.h"
# include "core/io/file_access_zip.h"
2016-03-12 14:44:12 +01:00
# include "core/io/stream_peer_ssl.h"
2017-03-05 16:44:50 +01:00
# include "core/io/stream_peer_tcp.h"
2015-09-24 23:06:15 +02:00
# include "main/input_default.h"
2014-02-10 02:10:30 +01:00
# include "performance.h"
2017-03-05 16:44:50 +01:00
# include "translation.h"
# include "version.h"
2017-09-24 11:32:05 +02:00
# include "version_hash.gen.h"
2014-02-10 02:10:30 +01:00
2017-07-19 22:00:46 +02:00
static ProjectSettings * globals = NULL ;
2017-03-05 16:44:50 +01:00
static Engine * engine = NULL ;
static InputMap * input_map = NULL ;
static bool _start_success = false ;
static ScriptDebugger * script_debugger = NULL ;
AudioServer * audio_server = NULL ;
2017-10-07 15:51:17 +02:00
ARVRServer * arvr_server = NULL ;
2017-10-21 13:02:06 +02:00
PhysicsServer * physics_server = NULL ;
Physics2DServer * physics_2d_server = NULL ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
static MessageQueue * message_queue = NULL ;
2014-02-10 02:10:30 +01:00
static Performance * performance = NULL ;
2017-01-26 01:55:59 +01:00
2017-03-05 16:44:50 +01:00
static PackedData * packed_data = NULL ;
2015-04-21 00:38:02 +02:00
# ifdef MINIZIP_ENABLED
2017-03-05 16:44:50 +01:00
static ZipArchive * zip_packed_data = NULL ;
2015-04-21 00:38:02 +02:00
# endif
2017-03-05 16:44:50 +01:00
static FileAccessNetworkClient * file_access_network_client = NULL ;
2014-02-10 02:10:30 +01:00
static TranslationServer * translation_server = NULL ;
static OS : : VideoMode video_mode ;
2017-03-05 16:44:50 +01:00
static bool init_maximized = false ;
static bool init_windowed = false ;
static bool init_fullscreen = false ;
static bool init_use_custom_pos = false ;
2017-04-07 16:17:16 +02:00
# ifdef DEBUG_ENABLED
2017-03-05 16:44:50 +01:00
static bool debug_collisions = false ;
static bool debug_navigation = false ;
2017-04-07 16:17:16 +02:00
# endif
2017-03-05 16:44:50 +01:00
static int frame_delay = 0 ;
2015-08-31 04:36:46 +02:00
static Vector2 init_custom_pos ;
2017-03-05 16:44:50 +01:00
static int video_driver_idx = - 1 ;
static int audio_driver_idx = - 1 ;
2014-02-10 02:10:30 +01:00
static String locale ;
2017-03-05 16:44:50 +01:00
static bool use_debug_profiler = false ;
static bool force_lowdpi = false ;
static int init_screen = - 1 ;
static bool use_vsync = true ;
static bool editor = false ;
2017-08-19 16:45:03 +02:00
static bool show_help = false ;
2017-08-30 12:40:35 +02:00
static bool disable_render_loop = false ;
static int fixed_fps = - 1 ;
2015-06-14 03:12:53 +02:00
2017-08-21 04:42:54 +02:00
static OS : : ProcessID allow_focus_steal_pid = 0 ;
2017-10-21 13:02:06 +02:00
void initialize_physics ( ) {
/// 3D Physics Server
physics_server = PhysicsServerManager : : new_server ( ProjectSettings : : get_singleton ( ) - > get ( PhysicsServerManager : : setting_property_name ) ) ;
if ( ! physics_server ) {
// Physics server not found, Use the default physics
physics_server = PhysicsServerManager : : new_default_server ( ) ;
}
ERR_FAIL_COND ( ! physics_server ) ;
physics_server - > init ( ) ;
/// 2D Physics server
physics_2d_server = Physics2DServerManager : : new_server ( ProjectSettings : : get_singleton ( ) - > get ( Physics2DServerManager : : setting_property_name ) ) ;
if ( ! physics_2d_server ) {
// Physics server not found, Use the default physics
physics_2d_server = Physics2DServerManager : : new_default_server ( ) ;
}
ERR_FAIL_COND ( ! physics_2d_server ) ;
physics_2d_server - > init ( ) ;
}
void finalize_physics ( ) {
physics_server - > finish ( ) ;
memdelete ( physics_server ) ;
physics_2d_server - > finish ( ) ;
memdelete ( physics_2d_server ) ;
}
2017-03-05 16:44:50 +01:00
static String unescape_cmdline ( const String & p_str ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
return p_str . replace ( " %20 " , " " ) ;
2014-02-10 02:10:30 +01:00
}
2017-09-24 11:32:05 +02:00
static String get_full_version_string ( ) {
String hash = String ( VERSION_HASH ) ;
if ( hash . length ( ) ! = 0 )
hash = " . " + hash . left ( 7 ) ;
return String ( VERSION_MKSTRING ) + hash ;
}
2014-02-10 02:10:30 +01:00
//#define DEBUG_INIT
# ifdef DEBUG_INIT
# define MAIN_PRINT(m_txt) print_line(m_txt)
# else
# define MAIN_PRINT(m_txt)
# endif
2017-03-05 16:44:50 +01:00
void Main : : print_help ( const char * p_binary ) {
2014-02-10 02:10:30 +01:00
2017-11-19 21:18:01 +01:00
print_line ( String ( VERSION_NAME ) + " v " + get_full_version_string ( ) + " - https://godotengine.org " ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " (c) 2007-2017 Juan Linietsky, Ariel Manzur. \n " ) ;
OS : : get_singleton ( ) - > print ( " (c) 2014-2017 Godot Engine contributors. \n " ) ;
OS : : get_singleton ( ) - > print ( " \n " ) ;
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " Usage: %s [options] [path to scene or 'project.godot' file] \n " , p_binary ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " \n " ) ;
OS : : get_singleton ( ) - > print ( " General options: \n " ) ;
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " -h, --help Display this help message. \n " ) ;
2017-09-24 11:32:05 +02:00
OS : : get_singleton ( ) - > print ( " --version Display the version string. \n " ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " -v, --verbose Use verbose stdout mode. \n " ) ;
OS : : get_singleton ( ) - > print ( " --quiet Quiet mode, silences stdout messages. Errors are still displayed. \n " ) ;
OS : : get_singleton ( ) - > print ( " \n " ) ;
OS : : get_singleton ( ) - > print ( " Run options: \n " ) ;
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
2017-08-19 16:45:03 +02:00
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 " ) ;
2014-02-10 02:10:30 +01:00
# endif
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " -l, --language <locale> Use a specific locale (<locale> being a two-letter code). \n " ) ;
OS : : get_singleton ( ) - > print ( " --path <directory> Path to a project (<directory> must contain a 'project.godot' file). \n " ) ;
2017-10-10 14:45:54 +02:00
OS : : get_singleton ( ) - > print ( " -u, --upwards Scan folders upwards for project.godot file. \n " ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " --main-pack <file> Path to a pack (.pck) file to load. \n " ) ;
OS : : get_singleton ( ) - > print ( " --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate'). \n " ) ;
OS : : get_singleton ( ) - > print ( " --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address). \n " ) ;
OS : : get_singleton ( ) - > print ( " --remote-fs-password <password> Password for remote filesystem. \n " ) ;
OS : : get_singleton ( ) - > print ( " --audio-driver <driver> Audio driver ( " ) ;
for ( int i = 0 ; i < OS : : get_singleton ( ) - > get_audio_driver_count ( ) ; i + + ) {
if ( i ! = 0 )
OS : : get_singleton ( ) - > print ( " , " ) ;
OS : : get_singleton ( ) - > print ( " '%s' " , OS : : get_singleton ( ) - > get_audio_driver_name ( i ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " ). \n " ) ;
OS : : get_singleton ( ) - > print ( " --video-driver <driver> Video driver ( " ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < OS : : get_singleton ( ) - > get_video_driver_count ( ) ; i + + ) {
if ( i ! = 0 )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > print ( " , " ) ;
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " '%s' " , OS : : get_singleton ( ) - > get_video_driver_name ( i ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " ). \n " ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " \n " ) ;
2017-08-19 16:45:03 +02:00
2017-08-19 16:45:03 +02:00
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 ( " --resolution <W>x<H> Request window resolution. \n " ) ;
OS : : get_singleton ( ) - > print ( " --position <X>,<Y> Request window position. \n " ) ;
2017-09-12 16:40:18 +02:00
OS : : get_singleton ( ) - > print ( " --low-dpi Force low-DPI mode (macOS and Windows only). \n " ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " --no-window Disable window creation (Windows only). Useful together with --script. \n " ) ;
OS : : get_singleton ( ) - > print ( " \n " ) ;
2017-08-19 22:47:27 +02:00
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Debug options: \n " ) ;
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " -d, --debug Debug (local stdout debugger). \n " ) ;
2017-08-19 16:45:03 +02:00
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 ( " --remote-debug <address> Remote debug (<host/IP>:<port> address). \n " ) ;
# ifdef DEBUG_ENABLED
OS : : get_singleton ( ) - > print ( " --debug-collisions Show collisions shapes when running the scene. \n " ) ;
OS : : get_singleton ( ) - > print ( " --debug-navigation Show navigation polygons when running the scene. \n " ) ;
# endif
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds). \n " ) ;
OS : : get_singleton ( ) - > print ( " --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed). \n " ) ;
2017-08-30 12:40:35 +02:00
OS : : get_singleton ( ) - > print ( " --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script. \n " ) ;
2017-09-08 03:01:49 +02:00
OS : : get_singleton ( ) - > print ( " --disable-crash-handler Disable crash handler when supported by the platform code. \n " ) ;
2017-09-24 20:24:41 +02:00
OS : : get_singleton ( ) - > print ( " --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization. \n " ) ;
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " \n " ) ;
OS : : get_singleton ( ) - > print ( " Standalone tools: \n " ) ;
OS : : get_singleton ( ) - > print ( " -s, --script <script> Run a script. \n " ) ;
2017-08-19 22:47:27 +02:00
# ifdef TOOLS_ENABLED
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " --export <target> Export the project using the given export target. \n " ) ;
OS : : get_singleton ( ) - > print ( " --export-debug Use together with --export, enables debug mode for the template. \n " ) ;
2017-09-24 11:32:05 +02:00
OS : : get_singleton ( ) - > print ( " --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found. \n " ) ;
2017-06-21 11:09:30 +02:00
OS : : get_singleton ( ) - > print ( " --no-docbase Disallow dumping the base types (used with --doctool). \n " ) ;
2017-08-19 16:45:03 +02:00
# ifdef DEBUG_METHODS_ENABLED
OS : : get_singleton ( ) - > print ( " --gdnative-generate-json-api Generate JSON dump of the Godot API for GDNative bindings. \n " ) ;
# endif
OS : : get_singleton ( ) - > print ( " --test <test> Run a unit test ( " ) ;
const char * * test_names = tests_get_names ( ) ;
const char * comma = " " ;
while ( * test_names ) {
OS : : get_singleton ( ) - > print ( " %s'%s' " , comma , * test_names ) ;
test_names + + ;
comma = " , " ;
}
OS : : get_singleton ( ) - > print ( " ). \n " ) ;
2014-02-10 02:10:30 +01:00
# endif
}
2017-03-05 16:44:50 +01:00
Error Main : : setup ( const char * execpath , int argc , char * argv [ ] , bool p_second_phase ) {
2014-02-10 02:10:30 +01:00
RID_OwnerBase : : init_rid ( ) ;
OS : : get_singleton ( ) - > initialize_core ( ) ;
2017-01-13 16:51:14 +01:00
2017-03-05 16:44:50 +01:00
engine = memnew ( Engine ) ;
2017-01-13 16:51:14 +01:00
2017-01-03 03:03:46 +01:00
ClassDB : : init ( ) ;
2014-02-10 02:10:30 +01:00
MAIN_PRINT ( " Main: Initialize CORE " ) ;
register_core_types ( ) ;
register_core_driver_types ( ) ;
MAIN_PRINT ( " Main: Initialize Globals " ) ;
2017-08-07 12:17:31 +02:00
Thread : : _main_thread_id = Thread : : get_caller_id ( ) ;
2014-02-10 02:10:30 +01:00
2017-07-19 22:00:46 +02:00
globals = memnew ( ProjectSettings ) ;
2017-03-05 16:44:50 +01:00
input_map = memnew ( InputMap ) ;
2014-02-10 02:10:30 +01:00
2017-01-05 13:16:00 +01:00
register_core_settings ( ) ; //here globals is present
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
translation_server = memnew ( TranslationServer ) ;
performance = memnew ( Performance ) ;
2017-10-09 23:49:17 +02:00
ClassDB : : register_class < Performance > ( ) ;
2017-11-13 21:46:57 +01:00
engine - > add_singleton ( Engine : : Singleton ( " Performance " , performance ) ) ;
2014-02-10 02:10:30 +01:00
2017-09-18 21:29:23 +02:00
GLOBAL_DEF ( " debug/settings/crash_handler/message " , String ( " Please include this when reporting the bug on https://github.com/godotengine/godot/issues " ) ) ;
2017-09-08 03:01:49 +02:00
2014-02-10 02:10:30 +01:00
MAIN_PRINT ( " Main: Parse CMDLine " ) ;
/* argument parsing and main creation */
List < String > args ;
List < String > main_args ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < argc ; i + + ) {
2014-02-10 02:10:30 +01:00
2014-02-18 14:37:22 +01:00
args . push_back ( String : : utf8 ( argv [ i ] ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
List < String > : : Element * I = args . front ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
I = args . front ( ) ;
2014-02-10 02:10:30 +01:00
while ( I ) {
2017-03-05 16:44:50 +01:00
I - > get ( ) = unescape_cmdline ( I - > get ( ) . strip_escapes ( ) ) ;
I = I - > next ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
I = args . front ( ) ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
String video_driver = " " ;
String audio_driver = " " ;
String game_path = " . " ;
2017-10-10 14:45:54 +02:00
bool upwards = false ;
2014-02-10 02:10:30 +01:00
String debug_mode ;
String debug_host ;
2014-06-28 04:21:45 +02:00
String main_pack ;
2017-03-05 16:44:50 +01:00
bool quiet_stdout = false ;
int rtm = - 1 ;
2014-02-10 02:10:30 +01:00
String remotefs ;
String remotefs_pass ;
Vector < String > breakpoints ;
2017-03-05 16:44:50 +01:00
bool use_custom_res = true ;
bool force_res = false ;
2014-02-10 02:10:30 +01:00
2014-06-28 04:21:45 +02:00
packed_data = PackedData : : get_singleton ( ) ;
if ( ! packed_data )
packed_data = memnew ( PackedData ) ;
2014-02-10 02:10:30 +01:00
# ifdef MINIZIP_ENABLED
2016-03-09 00:00:52 +01:00
2015-05-07 01:37:25 +02:00
//XXX: always get_singleton() == 0x0
2015-04-21 00:38:02 +02:00
zip_packed_data = ZipArchive : : get_singleton ( ) ;
2015-05-07 01:37:25 +02:00
//TODO: remove this temporary fix
if ( ! zip_packed_data ) {
zip_packed_data = memnew ( ZipArchive ) ;
}
2015-04-21 00:38:02 +02:00
packed_data - > add_pack_source ( zip_packed_data ) ;
2014-02-10 02:10:30 +01:00
# endif
2017-08-19 16:45:03 +02:00
I = args . front ( ) ;
2017-03-05 16:44:50 +01:00
while ( I ) {
2016-06-18 21:03:00 +02:00
2017-03-05 16:44:50 +01:00
List < String > : : Element * N = I - > next ( ) ;
2014-02-10 02:10:30 +01:00
2017-08-19 16:45:03 +02:00
if ( I - > get ( ) = = " -h " | | I - > get ( ) = = " --help " | | I - > get ( ) = = " /? " ) { // display help
2016-03-09 00:00:52 +01:00
2017-08-19 16:45:03 +02:00
show_help = true ;
2014-02-10 02:10:30 +01:00
goto error ;
2016-03-09 00:00:52 +01:00
2017-09-24 11:32:05 +02:00
} else if ( I - > get ( ) = = " --version " ) {
print_line ( get_full_version_string ( ) ) ;
goto error ;
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --resolution " ) { // force resolution
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
String vm = I - > next ( ) - > get ( ) ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
if ( vm . find ( " x " ) = = - 1 ) { // invalid parameter format
2016-03-09 00:00:52 +01:00
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Invalid resolution '%s', it should be e.g. '1280x720'. \n " , vm . utf8 ( ) . get_data ( ) ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
int w = vm . get_slice ( " x " , 0 ) . to_int ( ) ;
int h = vm . get_slice ( " x " , 1 ) . to_int ( ) ;
2016-03-09 00:00:52 +01:00
2017-08-19 16:45:03 +02:00
if ( w < = 0 | | h < = 0 ) {
2016-03-09 00:00:52 +01:00
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Invalid resolution '%s', width and height must be above 0. \n " , vm . utf8 ( ) . get_data ( ) ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
video_mode . width = w ;
video_mode . height = h ;
force_res = true ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing resolution argument, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --position " ) { // set window position
2015-08-31 04:36:46 +02:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
String vm = I - > next ( ) - > get ( ) ;
2015-08-31 04:36:46 +02:00
2017-06-21 11:09:30 +02:00
if ( vm . find ( " , " ) = = - 1 ) { // invalid parameter format
2015-08-31 04:36:46 +02:00
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Invalid position '%s', it should be e.g. '80,128'. \n " , vm . utf8 ( ) . get_data ( ) ) ;
2015-08-31 04:36:46 +02:00
goto error ;
}
2017-06-21 11:09:30 +02:00
int x = vm . get_slice ( " , " , 0 ) . to_int ( ) ;
int y = vm . get_slice ( " , " , 1 ) . to_int ( ) ;
2015-08-31 04:36:46 +02:00
2017-03-05 16:44:50 +01:00
init_custom_pos = Point2 ( x , y ) ;
init_use_custom_pos = true ;
2015-08-31 04:36:46 +02:00
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2015-08-31 04:36:46 +02:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing position argument, aborting. \n " ) ;
2015-08-31 04:36:46 +02:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -m " | | I - > get ( ) = = " --maximized " ) { // force maximized window
2015-08-31 04:36:46 +02:00
2017-03-05 16:44:50 +01:00
init_maximized = true ;
2017-10-24 21:35:28 +02:00
video_mode . maximized = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -w " | | I - > get ( ) = = " --windowed " ) { // force windowed window
2015-08-31 04:36:46 +02:00
2017-03-05 16:44:50 +01:00
init_windowed = true ;
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --profiling " ) { // enable profiling
2015-12-12 16:06:53 +01:00
2017-03-05 16:44:50 +01:00
use_debug_profiler = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --video-driver " ) { // force video driver
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
video_driver = I - > next ( ) - > get ( ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing video driver argument, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -l " | | I - > get ( ) = = " --language " ) { // language
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
locale = I - > next ( ) - > get ( ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing language argument, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --low-dpi " ) { // force low DPI (macOS only)
2016-05-30 05:28:29 +02:00
2017-03-05 16:44:50 +01:00
force_lowdpi = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --remote-fs " ) { // remote filesystem
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
remotefs = I - > next ( ) - > get ( ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing remote filesystem address, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --remote-fs-password " ) { // remote filesystem password
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
remotefs_pass = I - > next ( ) - > get ( ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing remote filesystem password, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --render-thread " ) { // render thread mode
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
if ( I - > next ( ) - > get ( ) = = " safe " )
rtm = OS : : RENDER_THREAD_SAFE ;
else if ( I - > next ( ) - > get ( ) = = " unsafe " )
rtm = OS : : RENDER_THREAD_UNSAFE ;
else if ( I - > next ( ) - > get ( ) = = " separate " )
rtm = OS : : RENDER_SEPARATE_THREAD ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing render thread mode argument, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --audio-driver " ) { // audio driver
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
audio_driver = I - > next ( ) - > get ( ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing audio driver argument, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2016-03-09 00:00:52 +01:00
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -f " | | I - > get ( ) = = " --fullscreen " ) { // force fullscreen
2016-03-09 00:00:52 +01:00
2015-08-31 04:36:46 +02:00
//video_mode.fullscreen=false;
2017-03-05 16:44:50 +01:00
init_fullscreen = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -e " | | I - > get ( ) = = " --editor " ) { // starts editor
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
editor = true ;
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --no-window " ) { // disable window creation, Windows only
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_no_window_mode ( true ) ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --quiet " ) { // quieter output
2014-08-02 03:10:38 +02:00
2017-03-05 16:44:50 +01:00
quiet_stdout = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -v " | | I - > get ( ) = = " --verbose " ) { // verbose output
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > _verbose_stdout = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --path " ) { // set path of project to start or edit
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
String p = I - > next ( ) - > get ( ) ;
2017-03-05 16:44:50 +01:00
if ( OS : : get_singleton ( ) - > set_cwd ( p ) = = OK ) {
2014-02-10 02:10:30 +01:00
//nothing
} else {
2017-03-05 16:44:50 +01:00
game_path = I - > next ( ) - > get ( ) ; //use game_path instead
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing relative or absolute path, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-10-10 14:45:54 +02:00
} else if ( I - > get ( ) = = " -u " | | I - > get ( ) = = " --upwards " ) { // scan folders upwards
upwards = true ;
2017-05-01 17:44:52 +02:00
} else if ( I - > get ( ) . ends_with ( " project.godot " ) ) {
String path ;
String file = I - > get ( ) ;
int sep = MAX ( file . find_last ( " / " ) , file . find_last ( " \\ " ) ) ;
if ( sep = = - 1 )
path = " . " ;
else {
path = file . substr ( 0 , sep ) ;
}
if ( OS : : get_singleton ( ) - > set_cwd ( path ) = = OK ) {
// path already specified, don't override
} else {
game_path = path ;
}
# ifdef TOOLS_ENABLED
editor = true ;
# endif
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " -b " | | I - > get ( ) = = " --breakpoints " ) { // add breakpoints
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
String bplist = I - > next ( ) - > get ( ) ;
2017-03-05 16:44:50 +01:00
breakpoints = bplist . split ( " , " ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing list of breakpoints, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --frame-delay " ) { // force frame delay
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
frame_delay = I - > next ( ) - > get ( ) . to_int ( ) ;
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing frame delay argument, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --time-scale " ) { // force time scale
2014-09-21 06:43:42 +02:00
if ( I - > next ( ) ) {
2017-01-13 16:51:14 +01:00
Engine : : get_singleton ( ) - > set_time_scale ( I - > next ( ) - > get ( ) . to_double ( ) ) ;
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2014-09-21 06:43:42 +02:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing time scale argument, aborting. \n " ) ;
2014-09-21 06:43:42 +02:00
goto error ;
}
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --main-pack " ) {
2014-06-28 04:21:45 +02:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
main_pack = I - > next ( ) - > get ( ) ;
2014-06-28 04:21:45 +02:00
N = I - > next ( ) - > next ( ) ;
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing path to main pack file, aborting. \n " ) ;
2014-06-28 04:21:45 +02:00
goto error ;
} ;
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " -d " | | I - > get ( ) = = " --debug " ) {
2017-03-05 16:44:50 +01:00
debug_mode = " local " ;
2017-04-07 16:17:16 +02:00
# ifdef DEBUG_ENABLED
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --debug-collisions " ) {
2017-03-05 16:44:50 +01:00
debug_collisions = true ;
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --debug-navigation " ) {
2017-03-05 16:44:50 +01:00
debug_navigation = true ;
2017-04-07 16:17:16 +02:00
# endif
2017-06-21 11:09:30 +02:00
} else if ( I - > get ( ) = = " --remote-debug " ) {
2014-02-10 02:10:30 +01:00
if ( I - > next ( ) ) {
2017-03-05 16:44:50 +01:00
debug_mode = " remote " ;
debug_host = I - > next ( ) - > get ( ) ;
2017-08-19 16:45:03 +02:00
if ( debug_host . find ( " : " ) = = - 1 ) { // wrong address
OS : : get_singleton ( ) - > print ( " Invalid debug host address, it should be of the form <host/IP>:<port>. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
2015-09-10 05:10:54 +02:00
}
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing remote debug host address, aborting. \n " ) ;
2014-02-10 02:10:30 +01:00
goto error ;
2016-09-14 04:02:18 +02:00
}
2017-08-19 16:45:03 +02:00
} else if ( I - > get ( ) = = " --allow_focus_steal_pid " ) { // not exposed to user
2016-09-14 04:02:18 +02:00
if ( I - > next ( ) ) {
2017-08-21 04:42:54 +02:00
allow_focus_steal_pid = I - > next ( ) - > get ( ) . to_int64 ( ) ;
2017-03-05 16:44:50 +01:00
N = I - > next ( ) - > next ( ) ;
2016-09-14 04:02:18 +02:00
} else {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Missing editor PID argument, aborting. \n " ) ;
2016-09-14 04:02:18 +02:00
goto error ;
2014-02-10 02:10:30 +01:00
}
2017-08-30 12:40:35 +02:00
} else if ( I - > get ( ) = = " --disable-render-loop " ) {
disable_render_loop = true ;
} else if ( I - > get ( ) = = " --fixed-fps " ) {
if ( I - > next ( ) ) {
fixed_fps = I - > next ( ) - > get ( ) . to_int ( ) ;
N = I - > next ( ) - > next ( ) ;
} else {
OS : : get_singleton ( ) - > print ( " Missing fixed-fps argument, aborting. \n " ) ;
goto error ;
}
2017-09-08 03:01:49 +02:00
} else if ( I - > get ( ) = = " --disable-crash-handler " ) {
OS : : get_singleton ( ) - > disable_crash_handler ( ) ;
2014-02-10 02:10:30 +01:00
} else {
//test for game path
2017-03-05 16:44:50 +01:00
bool gpfound = false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( ! I - > get ( ) . begins_with ( " - " ) & & game_path = = " " ) {
DirAccess * da = DirAccess : : open ( I - > get ( ) ) ;
if ( da ! = NULL ) {
game_path = I - > get ( ) ;
gpfound = true ;
2014-02-10 02:10:30 +01:00
memdelete ( da ) ;
}
}
if ( ! gpfound ) {
main_args . push_back ( I - > get ( ) ) ;
}
}
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
I = N ;
2014-02-10 02:10:30 +01:00
}
2017-07-18 02:05:38 +02:00
GLOBAL_DEF ( " memory/limits/multithreaded_server/rid_pool_prealloc " , 60 ) ;
GLOBAL_DEF ( " network/limits/debugger_stdout/max_chars_per_second " , 2048 ) ;
2017-01-05 13:16:00 +01:00
2014-02-10 02:10:30 +01:00
if ( debug_mode = = " remote " ) {
2017-03-05 16:44:50 +01:00
ScriptDebuggerRemote * sdr = memnew ( ScriptDebuggerRemote ) ;
2017-06-10 16:28:18 +02:00
uint16_t debug_port = 6007 ;
2017-03-05 16:44:50 +01:00
if ( debug_host . find ( " : " ) ! = - 1 ) {
2017-05-08 22:22:28 +02:00
int sep_pos = debug_host . find_last ( " : " ) ;
debug_port = debug_host . substr ( sep_pos + 1 , debug_host . length ( ) ) . to_int ( ) ;
debug_host = debug_host . substr ( 0 , sep_pos ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Error derr = sdr - > connect_to_host ( debug_host , debug_port ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( derr ! = OK ) {
2014-02-10 02:10:30 +01:00
memdelete ( sdr ) ;
} else {
2017-03-05 16:44:50 +01:00
script_debugger = sdr ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
} else if ( debug_mode = = " local " ) {
2016-05-22 02:18:16 +02:00
2017-03-05 16:44:50 +01:00
script_debugger = memnew ( ScriptDebuggerLocal ) ;
2014-02-10 02:10:30 +01:00
}
2017-01-05 13:16:00 +01:00
FileAccessNetwork : : configure ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( remotefs ! = " " ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
file_access_network_client = memnew ( FileAccessNetworkClient ) ;
2014-02-10 02:10:30 +01:00
int port ;
2017-03-05 16:44:50 +01:00
if ( remotefs . find ( " : " ) ! = - 1 ) {
port = remotefs . get_slicec ( ' : ' , 1 ) . to_int ( ) ;
remotefs = remotefs . get_slicec ( ' : ' , 0 ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
port = 6010 ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Error err = file_access_network_client - > connect ( remotefs , port , remotefs_pass ) ;
2014-02-10 02:10:30 +01:00
if ( err ) {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > printerr ( " Could not connect to remotefs: %s:%i. \n " , remotefs . utf8 ( ) . get_data ( ) , port ) ;
2014-02-10 02:10:30 +01:00
goto error ;
}
FileAccess : : make_default < FileAccessNetwork > ( FileAccess : : ACCESS_RESOURCES ) ;
}
if ( script_debugger ) {
//there is a debugger, parse breakpoints
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < breakpoints . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
String bp = breakpoints [ i ] ;
2017-03-05 16:44:50 +01:00
int sp = bp . find_last ( " : " ) ;
if ( sp = = - 1 ) {
ERR_EXPLAIN ( " Invalid breakpoint: ' " + bp + " ', expected file:line format. " ) ;
ERR_CONTINUE ( sp = = - 1 ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
script_debugger - > insert_breakpoint ( bp . substr ( sp + 1 , bp . length ( ) ) . to_int ( ) , bp . substr ( 0 , sp ) ) ;
2014-02-10 02:10:30 +01:00
}
}
# ifdef TOOLS_ENABLED
if ( editor ) {
packed_data - > set_disabled ( true ) ;
2017-07-19 22:00:46 +02:00
globals - > set_disable_feature_overrides ( true ) ;
2017-03-05 16:44:50 +01:00
StreamPeerSSL : : initialize_certs = false ; //will be initialized by editor
2014-02-10 02:10:30 +01:00
}
# endif
2017-10-10 14:45:54 +02:00
if ( globals - > setup ( game_path , main_pack , upwards ) ! = OK ) {
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
editor = false ;
2014-02-10 02:10:30 +01:00
# else
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > print ( " Error: Could not load game path '%s'. \n " , game_path . ascii ( ) . get_data ( ) ) ;
2014-02-10 02:10:30 +01:00
goto error ;
# endif
}
2017-11-21 10:35:01 +01:00
GLOBAL_DEF ( " logging/file_logging/enable_file_logging " , true ) ;
GLOBAL_DEF ( " logging/file_logging/log_path " , " user://logs/log.txt " ) ;
GLOBAL_DEF ( " logging/file_logging/max_log_files " , 10 ) ;
if ( FileAccess : : get_create_func ( FileAccess : : ACCESS_USERDATA ) & & GLOBAL_GET ( " logging/file_logging/enable_file_logging " ) ) {
String base_path = GLOBAL_GET ( " logging/file_logging/log_path " ) ;
int max_files = GLOBAL_GET ( " logging/file_logging/max_log_files " ) ;
OS : : get_singleton ( ) - > add_logger ( memnew ( RotatedFileLogger ( base_path , max_files ) ) ) ;
}
2014-02-10 02:10:30 +01:00
if ( editor ) {
2017-08-13 16:21:45 +02:00
Engine : : get_singleton ( ) - > set_editor_hint ( true ) ;
2017-06-21 11:09:30 +02:00
main_args . push_back ( " --editor " ) ;
2017-03-05 16:44:50 +01:00
init_maximized = true ;
2017-10-24 21:35:28 +02:00
video_mode . maximized = true ;
2017-03-05 16:44:50 +01:00
use_custom_res = false ;
2014-02-10 02:10:30 +01:00
}
2017-07-19 22:00:46 +02:00
if ( bool ( ProjectSettings : : get_singleton ( ) - > get ( " application/run/disable_stdout " ) ) ) {
2017-03-05 16:44:50 +01:00
quiet_stdout = true ;
2014-08-02 03:10:38 +02:00
}
2017-07-19 22:00:46 +02:00
if ( bool ( ProjectSettings : : get_singleton ( ) - > get ( " application/run/disable_stderr " ) ) ) {
2015-06-30 16:28:43 +02:00
_print_error_enabled = false ;
} ;
2014-08-02 03:10:38 +02:00
if ( quiet_stdout )
2017-03-05 16:44:50 +01:00
_print_line_enabled = false ;
2014-08-02 03:10:38 +02:00
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_cmdline ( execpath , main_args ) ;
# ifdef TOOLS_ENABLED
2017-10-05 20:34:34 +02:00
if ( main_args . size ( ) = = 0 & & ( ! ProjectSettings : : get_singleton ( ) - > has_setting ( " application/run/main_loop_type " ) ) & & ( ! ProjectSettings : : get_singleton ( ) - > has_setting ( " application/run/main_scene " ) | | String ( ProjectSettings : : get_singleton ( ) - > get ( " application/run/main_scene " ) ) = = " " ) )
2017-03-05 16:44:50 +01:00
use_custom_res = false ; //project manager (run without arguments)
2014-02-10 02:10:30 +01:00
# endif
2016-06-05 06:19:42 +02:00
if ( editor )
input_map - > load_default ( ) ; //keys for editor
else
input_map - > load_from_globals ( ) ; //keys for game
2014-02-10 02:10:30 +01:00
2017-07-18 02:05:38 +02:00
//if (video_driver == "") // useless for now, so removing
// video_driver = GLOBAL_DEF("display/driver/name", Variant((const char *)OS::get_singleton()->get_video_driver_name(0)));
2014-02-10 02:10:30 +01:00
2017-11-09 17:55:51 +01:00
GLOBAL_DEF ( " display/window/size/width " , 1024 ) ;
GLOBAL_DEF ( " display/window/size/height " , 600 ) ;
GLOBAL_DEF ( " display/window/size/resizable " , true ) ;
GLOBAL_DEF ( " display/window/size/borderless " , false ) ;
GLOBAL_DEF ( " display/window/size/fullscreen " , false ) ;
GLOBAL_DEF ( " display/window/size/test_width " , 0 ) ;
GLOBAL_DEF ( " display/window/size/test_height " , 0 ) ;
2017-11-09 17:01:29 +01:00
if ( use_custom_res ) {
if ( ! force_res ) {
2017-11-09 17:55:51 +01:00
video_mode . width = GLOBAL_GET ( " display/window/size/width " ) ;
video_mode . height = GLOBAL_GET ( " display/window/size/height " ) ;
2017-11-09 17:01:29 +01:00
if ( globals - > has_setting ( " display/window/size/test_width " ) & & globals - > has_setting ( " display/window/size/test_height " ) ) {
int tw = globals - > get ( " display/window/size/test_width " ) ;
int th = globals - > get ( " display/window/size/test_height " ) ;
if ( tw > 0 & & th > 0 ) {
video_mode . width = tw ;
video_mode . height = th ;
}
}
2014-09-15 16:33:30 +02:00
}
2017-11-09 17:01:29 +01:00
2017-11-09 17:55:51 +01:00
video_mode . resizable = GLOBAL_GET ( " display/window/size/resizable " ) ;
video_mode . borderless_window = GLOBAL_GET ( " display/window/size/borderless " ) ;
video_mode . fullscreen = GLOBAL_GET ( " display/window/size/fullscreen " ) ;
2014-09-15 16:33:30 +02:00
}
2014-02-10 02:10:30 +01:00
2017-11-09 17:01:29 +01:00
if ( ! force_lowdpi ) {
OS : : get_singleton ( ) - > _allow_hidpi = GLOBAL_DEF ( " display/window/dpi/allow_hidpi " , false ) ;
}
use_vsync = GLOBAL_DEF ( " display/window/vsync/use_vsync " , true ) ;
2017-07-19 22:00:46 +02:00
GLOBAL_DEF ( " rendering/quality/intended_usage/framebuffer_allocation " , 2 ) ;
GLOBAL_DEF ( " rendering/quality/intended_usage/framebuffer_allocation.mobile " , 3 ) ;
2017-10-05 21:41:42 +02:00
if ( editor ) {
OS : : get_singleton ( ) - > _allow_hidpi = true ; //editors always in hidpi
}
2017-07-18 02:05:38 +02:00
Engine : : get_singleton ( ) - > _pixel_snap = GLOBAL_DEF ( " rendering/quality/2d/use_pixel_snap " , false ) ;
OS : : get_singleton ( ) - > _keep_screen_on = GLOBAL_DEF ( " display/window/energy_saving/keep_screen_on " , true ) ;
2017-03-05 16:44:50 +01:00
if ( rtm = = - 1 ) {
rtm = GLOBAL_DEF ( " rendering/threads/thread_model " , OS : : RENDER_THREAD_SAFE ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( rtm > = 0 & & rtm < 3 ) {
2015-12-31 20:24:27 +01:00
if ( editor ) {
2017-03-05 16:44:50 +01:00
rtm = OS : : RENDER_THREAD_SAFE ;
2015-12-31 20:24:27 +01:00
}
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > _render_thread_mode = OS : : RenderThreadMode ( rtm ) ;
2015-12-31 20:24:27 +01:00
}
2014-02-10 02:10:30 +01:00
2017-08-19 16:45:03 +02:00
/* Determine audio and video drivers */
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < OS : : get_singleton ( ) - > get_video_driver_count ( ) ; i + + ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
if ( video_driver = = OS : : get_singleton ( ) - > get_video_driver_name ( i ) ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
video_driver_idx = i ;
2014-02-10 02:10:30 +01:00
break ;
}
}
2017-03-05 16:44:50 +01:00
if ( video_driver_idx < 0 ) {
2016-03-09 00:00:52 +01:00
2017-07-18 02:05:38 +02:00
//OS::get_singleton()->alert("Invalid Video Driver: " + video_driver);
2014-02-10 02:10:30 +01:00
video_driver_idx = 0 ;
//goto error;
}
2017-08-19 16:45:03 +02:00
if ( audio_driver = = " " ) { // specified in project.godot
audio_driver = GLOBAL_DEF ( " audio/driver " , OS : : get_singleton ( ) - > get_audio_driver_name ( 0 ) ) ;
}
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < OS : : get_singleton ( ) - > get_audio_driver_count ( ) ; i + + ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
if ( audio_driver = = OS : : get_singleton ( ) - > get_audio_driver_name ( i ) ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
audio_driver_idx = i ;
2014-02-10 02:10:30 +01:00
break ;
}
}
2017-03-05 16:44:50 +01:00
if ( audio_driver_idx < 0 ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > alert ( " Invalid Audio Driver: " + audio_driver ) ;
2016-01-31 22:47:13 +01:00
audio_driver_idx = 0 ;
//goto error;
2014-02-10 02:10:30 +01:00
}
{
2017-07-18 02:05:38 +02:00
String orientation = GLOBAL_DEF ( " display/window/handheld/orientation " , " landscape " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( orientation = = " portrait " )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_PORTRAIT ) ;
2017-03-05 16:44:50 +01:00
else if ( orientation = = " reverse_landscape " )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_REVERSE_LANDSCAPE ) ;
2017-03-05 16:44:50 +01:00
else if ( orientation = = " reverse_portrait " )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_REVERSE_PORTRAIT ) ;
2017-03-05 16:44:50 +01:00
else if ( orientation = = " sensor_landscape " )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_SENSOR_LANDSCAPE ) ;
2017-03-05 16:44:50 +01:00
else if ( orientation = = " sensor_portrait " )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_SENSOR_PORTRAIT ) ;
2017-03-05 16:44:50 +01:00
else if ( orientation = = " sensor " )
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_SENSOR ) ;
else
OS : : get_singleton ( ) - > set_screen_orientation ( OS : : SCREEN_LANDSCAPE ) ;
}
2017-03-05 16:44:50 +01:00
Engine : : get_singleton ( ) - > set_iterations_per_second ( GLOBAL_DEF ( " physics/common/fixed_fps " , 60 ) ) ;
2017-07-18 02:05:38 +02:00
Engine : : get_singleton ( ) - > set_target_fps ( GLOBAL_DEF ( " debug/settings/fps/force_fps " , 0 ) ) ;
2017-01-05 13:16:00 +01:00
2017-07-18 02:05:38 +02:00
GLOBAL_DEF ( " debug/settings/stdout/print_fps " , OS : : get_singleton ( ) - > is_stdout_verbose ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! OS : : get_singleton ( ) - > _verbose_stdout ) //overrided
2017-07-18 02:05:38 +02:00
OS : : get_singleton ( ) - > _verbose_stdout = GLOBAL_DEF ( " debug/settings/stdout/verbose_stdout " , false ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( frame_delay = = 0 ) {
2017-07-18 02:05:38 +02:00
frame_delay = GLOBAL_DEF ( " application/run/frame_delay_msec " , 0 ) ;
2016-07-09 17:34:30 +02:00
}
2017-11-22 18:40:43 +01:00
OS : : get_singleton ( ) - > set_low_processor_usage_mode ( GLOBAL_DEF ( " application/run/low_processor_mode " , false ) ) ;
OS : : get_singleton ( ) - > set_low_processor_usage_mode_sleep_usec ( GLOBAL_DEF ( " application/run/low_processor_mode_sleep_usec " , 8000 ) ) ;
2017-01-13 16:51:14 +01:00
Engine : : get_singleton ( ) - > set_frame_delay ( frame_delay ) ;
2016-07-09 17:34:30 +02:00
2017-03-05 16:44:50 +01:00
message_queue = memnew ( MessageQueue ) ;
2014-02-10 02:10:30 +01:00
2017-07-19 22:00:46 +02:00
ProjectSettings : : get_singleton ( ) - > register_global_defaults ( ) ;
2014-02-10 02:10:30 +01:00
if ( p_second_phase )
return setup2 ( ) ;
return OK ;
2017-03-05 16:44:50 +01:00
error :
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
video_driver = " " ;
audio_driver = " " ;
game_path = " " ;
2016-03-09 00:00:52 +01:00
args . clear ( ) ;
2014-02-10 02:10:30 +01:00
main_args . clear ( ) ;
2016-03-09 00:00:52 +01:00
2017-08-19 16:45:03 +02:00
if ( show_help )
print_help ( execpath ) ;
2014-02-10 02:10:30 +01:00
if ( performance )
memdelete ( performance ) ;
if ( input_map )
memdelete ( input_map ) ;
if ( translation_server )
2017-03-05 16:44:50 +01:00
memdelete ( translation_server ) ;
2014-02-10 02:10:30 +01:00
if ( globals )
memdelete ( globals ) ;
2017-01-13 16:51:14 +01:00
if ( engine )
memdelete ( engine ) ;
2014-02-10 02:10:30 +01:00
if ( script_debugger )
memdelete ( script_debugger ) ;
if ( packed_data )
memdelete ( packed_data ) ;
if ( file_access_network_client )
memdelete ( file_access_network_client ) ;
2015-04-21 00:38:02 +02:00
2017-03-05 16:44:50 +01:00
// Note 1: *zip_packed_data live into *packed_data
// Note 2: PackedData::~PackedData destroy this.
/*
2017-01-14 12:26:56 +01:00
# ifdef MINIZIP_ENABLED
if ( zip_packed_data )
memdelete ( zip_packed_data ) ;
# endif
*/
2015-04-21 00:38:02 +02:00
2015-10-30 12:56:07 +01:00
unregister_core_driver_types ( ) ;
2014-02-10 02:10:30 +01:00
unregister_core_types ( ) ;
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > _cmdline . clear ( ) ;
if ( message_queue )
2017-03-05 16:44:50 +01:00
memdelete ( message_queue ) ;
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > finalize_core ( ) ;
2017-03-05 16:44:50 +01:00
locale = String ( ) ;
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
return ERR_INVALID_PARAMETER ;
}
2017-08-22 17:21:41 +02:00
Error Main : : setup2 ( Thread : : ID p_main_tid_override ) {
if ( p_main_tid_override ) {
Thread : : _main_thread_id = p_main_tid_override ;
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > initialize ( video_mode , video_driver_idx , audio_driver_idx ) ;
2015-08-31 04:36:46 +02:00
if ( init_use_custom_pos ) {
OS : : get_singleton ( ) - > set_window_position ( init_custom_pos ) ;
}
2015-12-12 16:06:53 +01:00
2017-10-07 15:51:17 +02:00
// right moment to create and initialize the audio server
2017-01-15 20:06:14 +01:00
2017-03-05 16:44:50 +01:00
audio_server = memnew ( AudioServer ) ;
2017-01-15 20:06:14 +01:00
audio_server - > init ( ) ;
2017-10-07 15:51:17 +02:00
// also init our arvr_server from here
arvr_server = memnew ( ARVRServer ) ;
2016-06-06 00:14:33 +02:00
OS : : get_singleton ( ) - > set_use_vsync ( use_vsync ) ;
2014-02-10 02:10:30 +01:00
register_core_singletons ( ) ;
MAIN_PRINT ( " Main: Setup Logo " ) ;
# ifdef JAVASCRIPT_ENABLED
2017-08-21 21:15:36 +02:00
bool show_logo = false ;
# else
bool show_logo = true ;
2014-02-10 02:10:30 +01:00
# endif
2017-03-05 16:44:50 +01:00
if ( init_screen ! = - 1 ) {
2015-06-14 03:12:53 +02:00
OS : : get_singleton ( ) - > set_current_screen ( init_screen ) ;
}
2015-12-12 16:06:53 +01:00
if ( init_windowed ) {
//do none..
} else if ( init_maximized ) {
2015-06-14 03:12:53 +02:00
OS : : get_singleton ( ) - > set_window_maximized ( true ) ;
2015-12-12 16:06:53 +01:00
} else if ( init_fullscreen ) {
OS : : get_singleton ( ) - > set_window_fullscreen ( true ) ;
2015-06-14 03:12:53 +02:00
}
2017-04-10 01:02:04 +02:00
register_server_types ( ) ;
2015-09-04 04:24:55 +02:00
MAIN_PRINT ( " Main: Load Remaps " ) ;
2017-07-18 02:05:38 +02:00
Color clear = GLOBAL_DEF ( " rendering/environment/default_clear_color " , Color ( 0.3 , 0.3 , 0.3 ) ) ;
2017-01-05 13:16:00 +01:00
VisualServer : : get_singleton ( ) - > set_default_clear_color ( clear ) ;
2014-02-10 02:10:30 +01:00
if ( show_logo ) { //boot logo!
2017-07-18 02:05:38 +02:00
String boot_logo_path = GLOBAL_DEF ( " application/boot_splash/image " , String ( ) ) ;
bool boot_logo_scale = GLOBAL_DEF ( " application/boot_splash/fullsize " , true ) ;
2017-07-19 22:00:46 +02:00
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " application/boot_splash/image " , PropertyInfo ( Variant : : STRING , " application/boot_splash/image " , PROPERTY_HINT_FILE , " *.png " ) ) ;
2015-04-12 22:55:01 +02:00
2017-05-17 12:36:47 +02:00
Ref < Image > boot_logo ;
2015-04-12 22:55:01 +02:00
2015-09-04 04:24:55 +02:00
boot_logo_path = boot_logo_path . strip_edges ( ) ;
2017-03-05 16:44:50 +01:00
if ( boot_logo_path ! = String ( ) /*&& FileAccess::exists(boot_logo_path)*/ ) {
print_line ( " Boot splash path: " + boot_logo_path ) ;
2017-05-17 12:36:47 +02:00
boot_logo . instance ( ) ;
Error err = boot_logo - > load ( boot_logo_path ) ;
2016-07-03 23:19:22 +02:00
if ( err )
ERR_PRINTS ( " Non-existing or invalid boot splash at: " + boot_logo_path + " . Loading default splash. " ) ;
2015-04-12 22:55:01 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-17 12:36:47 +02:00
if ( boot_logo . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > _msec_splash = OS : : get_singleton ( ) - > get_ticks_msec ( ) ;
2017-07-18 02:05:38 +02:00
Color boot_bg = GLOBAL_DEF ( " application/boot_splash/bg_color " , clear ) ;
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > set_boot_image ( boot_logo , boot_bg , boot_logo_scale ) ;
2014-02-10 02:10:30 +01:00
# ifndef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
//no tools, so free the boot logo (no longer needed)
2017-07-19 22:00:46 +02:00
//ProjectSettings::get_singleton()->set("application/boot_logo",Image());
2014-02-10 02:10:30 +01:00
# endif
} else {
# ifndef NO_DEFAULT_BOOT_LOGO
2015-11-23 00:38:12 +01:00
MAIN_PRINT ( " Main: Create bootsplash " ) ;
2017-05-17 12:36:47 +02:00
Ref < Image > splash = memnew ( Image ( boot_splash_png ) ) ;
2014-02-10 02:10:30 +01:00
MAIN_PRINT ( " Main: ClearColor " ) ;
VisualServer : : get_singleton ( ) - > set_default_clear_color ( boot_splash_bg_color ) ;
MAIN_PRINT ( " Main: Image " ) ;
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > set_boot_image ( splash , boot_splash_bg_color , false ) ;
2014-02-10 02:10:30 +01:00
# endif
}
2017-09-15 18:41:11 +02:00
# ifdef TOOLS_ENABLED
2017-05-17 12:36:47 +02:00
Ref < Image > icon = memnew ( Image ( app_icon_png ) ) ;
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_icon ( icon ) ;
2017-09-15 18:41:11 +02:00
# endif
2014-02-10 02:10:30 +01:00
}
2016-04-08 01:30:00 +02:00
MAIN_PRINT ( " Main: DCC " ) ;
2017-07-18 02:05:38 +02:00
VisualServer : : get_singleton ( ) - > set_default_clear_color ( GLOBAL_DEF ( " rendering/environment/default_clear_color " , Color ( 0.3 , 0.3 , 0.3 ) ) ) ;
2016-04-08 01:30:00 +02:00
MAIN_PRINT ( " Main: END " ) ;
2017-07-18 02:05:38 +02:00
GLOBAL_DEF ( " application/config/icon " , String ( ) ) ;
2017-07-19 22:00:46 +02:00
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " application/config/icon " , PropertyInfo ( Variant : : STRING , " application/config/icon " , PROPERTY_HINT_FILE , " *.png,*.webp " ) ) ;
2014-02-10 02:10:30 +01:00
2017-07-18 02:05:38 +02:00
if ( bool ( GLOBAL_DEF ( " display/window/handheld/emulate_touchscreen " , false ) ) ) {
2016-06-18 21:03:00 +02:00
if ( ! OS : : get_singleton ( ) - > has_touchscreen_ui_hint ( ) & & Input : : get_singleton ( ) & & ! editor ) {
2015-08-29 22:16:11 +02:00
//only if no touchscreen ui hint, set emulation
2017-08-24 22:58:51 +02:00
InputDefault * id = Object : : cast_to < InputDefault > ( Input : : get_singleton ( ) ) ;
2015-08-29 22:16:11 +02:00
if ( id )
id - > set_emulate_touch ( true ) ;
}
}
2015-09-24 23:06:15 +02:00
2014-02-10 02:10:30 +01:00
MAIN_PRINT ( " Main: Load Remaps " ) ;
MAIN_PRINT ( " Main: Load Scene Types " ) ;
register_scene_types ( ) ;
2017-03-05 16:44:50 +01:00
GLOBAL_DEF ( " display/mouse_cursor/custom_image " , String ( ) ) ;
GLOBAL_DEF ( " display/mouse_cursor/custom_image_hotspot " , Vector2 ( ) ) ;
2017-07-19 22:00:46 +02:00
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " display/mouse_cursor/custom_image " , PropertyInfo ( Variant : : STRING , " display/mouse_cursor/custom_image " , PROPERTY_HINT_FILE , " *.png,*.webp " ) ) ;
2015-09-24 23:06:15 +02:00
2017-07-19 22:00:46 +02:00
if ( String ( ProjectSettings : : get_singleton ( ) - > get ( " display/mouse_cursor/custom_image " ) ) ! = String ( ) ) {
2015-09-24 23:06:15 +02:00
2015-11-24 14:42:05 +01:00
//print_line("use custom cursor");
2017-07-19 22:00:46 +02:00
Ref < Texture > cursor = ResourceLoader : : load ( ProjectSettings : : get_singleton ( ) - > get ( " display/mouse_cursor/custom_image " ) ) ;
2015-09-24 23:06:15 +02:00
if ( cursor . is_valid ( ) ) {
2017-01-14 12:26:56 +01:00
//print_line("loaded ok");
2017-07-19 22:00:46 +02:00
Vector2 hotspot = ProjectSettings : : get_singleton ( ) - > get ( " display/mouse_cursor/custom_image_hotspot " ) ;
2017-03-05 16:44:50 +01:00
Input : : get_singleton ( ) - > set_custom_mouse_cursor ( cursor , hotspot ) ;
2015-09-24 23:06:15 +02:00
}
}
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
2017-01-03 03:03:46 +01:00
ClassDB : : set_current_api ( ClassDB : : API_EDITOR ) ;
2014-02-10 02:10:30 +01:00
EditorNode : : register_editor_types ( ) ;
2016-10-01 22:04:10 +02:00
2017-01-03 03:03:46 +01:00
ClassDB : : set_current_api ( ClassDB : : API_CORE ) ;
2016-09-15 00:37:37 +02:00
2014-02-10 02:10:30 +01:00
# endif
2017-08-21 04:42:54 +02:00
if ( allow_focus_steal_pid ) {
OS : : get_singleton ( ) - > enable_for_stealing_focus ( allow_focus_steal_pid ) ;
}
2017-10-21 13:02:06 +02:00
MAIN_PRINT ( " Main: Load Modules, Physics, Drivers, Scripts " ) ;
2014-02-10 02:10:30 +01:00
2017-11-16 01:33:48 +01:00
register_platform_apis ( ) ;
2014-02-10 02:10:30 +01:00
register_module_types ( ) ;
2017-10-21 13:02:06 +02:00
initialize_physics ( ) ;
register_server_singletons ( ) ;
2014-02-10 02:10:30 +01:00
register_driver_types ( ) ;
2014-11-13 04:53:12 +01:00
ScriptServer : : init_languages ( ) ;
2014-02-10 02:10:30 +01:00
MAIN_PRINT ( " Main: Load Translations " ) ;
translation_server - > setup ( ) ; //register translations, load them, etc.
2017-03-05 16:44:50 +01:00
if ( locale ! = " " ) {
2014-02-10 02:10:30 +01:00
translation_server - > set_locale ( locale ) ;
}
translation_server - > load_translations ( ) ;
2017-06-28 22:00:18 +02:00
ResourceLoader : : load_translation_remaps ( ) ; //load remaps for resources
2014-02-10 02:10:30 +01:00
2017-01-25 18:30:40 +01:00
audio_server - > load_default_bus_layout ( ) ;
2014-02-10 02:10:30 +01:00
2016-05-22 02:18:16 +02:00
if ( use_debug_profiler & & script_debugger ) {
script_debugger - > profiling_start ( ) ;
}
2017-03-05 16:44:50 +01:00
_start_success = true ;
locale = String ( ) ;
2014-02-10 02:10:30 +01:00
2017-01-03 03:03:46 +01:00
ClassDB : : set_current_api ( ClassDB : : API_NONE ) ; //no more api is registered at this point
2016-09-15 00:37:37 +02:00
2016-09-18 00:01:11 +02:00
if ( OS : : get_singleton ( ) - > is_stdout_verbose ( ) ) {
2017-03-05 16:44:50 +01:00
print_line ( " CORE API HASH: " + itos ( ClassDB : : get_api_hash ( ClassDB : : API_CORE ) ) ) ;
print_line ( " EDITOR API HASH: " + itos ( ClassDB : : get_api_hash ( ClassDB : : API_EDITOR ) ) ) ;
2016-09-18 00:01:11 +02:00
}
2014-02-10 02:10:30 +01:00
MAIN_PRINT ( " Main: Done " ) ;
return OK ;
}
bool Main : : start ( ) {
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( ! _start_success , false ) ;
2014-02-10 02:10:30 +01:00
2017-09-15 18:41:11 +02:00
bool hasicon = false ;
2017-03-05 16:44:50 +01:00
bool editor = false ;
2014-02-10 02:10:30 +01:00
String doc_tool ;
2016-12-16 12:12:22 +01:00
List < String > removal_docs ;
2017-03-05 16:44:50 +01:00
bool doc_base = true ;
2014-02-10 02:10:30 +01:00
String game_path ;
String script ;
String test ;
2017-08-14 15:15:06 +02:00
String _export_preset ;
2017-03-05 16:44:50 +01:00
bool export_debug = false ;
2016-02-25 07:02:09 +01:00
bool project_manager_request = false ;
2017-08-19 16:45:03 +02:00
2014-02-10 02:10:30 +01:00
List < String > args = OS : : get_singleton ( ) - > get_cmdline_args ( ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < args . size ( ) ; i + + ) {
2015-11-01 17:50:44 +01:00
//parameters that do not have an argument to the right
2017-06-21 11:09:30 +02:00
if ( args [ i ] = = " --no-docbase " ) {
2017-03-05 16:44:50 +01:00
doc_base = false ;
2017-08-19 16:45:03 +02:00
} else if ( args [ i ] = = " -e " | | args [ i ] = = " --editor " ) {
2017-03-05 16:44:50 +01:00
editor = true ;
2017-08-19 16:45:03 +02:00
} else if ( args [ i ] = = " -p " | | args [ i ] = = " --project-manager " ) {
2016-02-25 07:02:09 +01:00
project_manager_request = true ;
2015-11-01 17:50:44 +01:00
} else if ( args [ i ] . length ( ) & & args [ i ] [ 0 ] ! = ' - ' & & game_path = = " " ) {
2017-03-05 16:44:50 +01:00
game_path = args [ i ] ;
2015-11-01 17:50:44 +01:00
}
2015-09-16 22:51:19 +02:00
//parameters that have an argument to the right
2017-03-05 16:44:50 +01:00
else if ( i < ( args . size ( ) - 1 ) ) {
bool parsed_pair = true ;
2017-06-21 11:09:30 +02:00
if ( args [ i ] = = " --doctool " ) {
2017-03-05 16:44:50 +01:00
doc_tool = args [ i + 1 ] ;
for ( int j = i + 2 ; j < args . size ( ) ; j + + )
2016-12-16 12:12:22 +01:00
removal_docs . push_back ( args [ j ] ) ;
2017-08-19 16:45:03 +02:00
} else if ( args [ i ] = = " -s " | | args [ i ] = = " --script " ) {
2017-03-05 16:44:50 +01:00
script = args [ i + 1 ] ;
2017-06-21 11:09:30 +02:00
} else if ( args [ i ] = = " --test " ) {
2017-03-05 16:44:50 +01:00
test = args [ i + 1 ] ;
2017-06-21 11:09:30 +02:00
} else if ( args [ i ] = = " --export " ) {
2017-03-05 16:44:50 +01:00
editor = true ; //needs editor
2017-08-18 16:17:35 +02:00
if ( i + 1 < args . size ( ) ) {
_export_preset = args [ i + 1 ] ;
} else {
ERR_PRINT ( " Export preset name not specified " ) ;
return false ;
}
2017-06-21 11:09:30 +02:00
} else if ( args [ i ] = = " --export-debug " ) {
2017-03-05 16:44:50 +01:00
editor = true ; //needs editor
2017-08-18 16:17:35 +02:00
if ( i + 1 < args . size ( ) ) {
_export_preset = args [ i + 1 ] ;
} else {
ERR_PRINT ( " Export preset name not specified " ) ;
return false ;
}
2017-03-05 16:44:50 +01:00
export_debug = true ;
2015-11-01 17:50:44 +01:00
} else {
// The parameter does not match anything known, don't skip the next argument
2017-03-05 16:44:50 +01:00
parsed_pair = false ;
2015-11-01 17:50:44 +01:00
}
if ( parsed_pair ) {
i + + ;
2015-09-16 22:51:19 +02:00
}
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
GLOBAL_DEF ( " editor/active " , editor ) ;
2014-02-10 02:10:30 +01:00
String main_loop_type ;
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
if ( doc_tool ! = " " ) {
2014-02-10 02:10:30 +01:00
2017-09-12 22:42:36 +02:00
{
DirAccessRef da = DirAccess : : open ( doc_tool ) ;
if ( ! da ) {
ERR_EXPLAIN ( " Argument supplied to --doctool must be a base godot build directory " ) ;
ERR_FAIL_V ( false ) ;
}
}
2014-02-10 02:10:30 +01:00
DocData doc ;
doc . generate ( doc_base ) ;
DocData docsrc ;
2017-09-13 09:13:23 +02:00
Map < String , String > doc_data_classes ;
2017-09-12 22:42:36 +02:00
Set < String > checked_paths ;
print_line ( " Loading docs.. " ) ;
2017-09-13 09:13:23 +02:00
for ( int i = 0 ; i < _doc_data_class_path_count ; i + + ) {
2017-09-12 22:42:36 +02:00
String path = doc_tool . plus_file ( _doc_data_class_paths [ i ] . path ) ;
String name = _doc_data_class_paths [ i ] . name ;
2017-09-13 09:13:23 +02:00
doc_data_classes [ name ] = path ;
2017-09-12 22:42:36 +02:00
if ( ! checked_paths . has ( path ) ) {
checked_paths . insert ( path ) ;
docsrc . load_classes ( path ) ;
2017-09-13 09:13:23 +02:00
print_line ( " Loading docs from: " + path ) ;
2017-09-12 22:42:36 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-09-12 22:42:36 +02:00
String index_path = doc_tool . plus_file ( " doc/classes " ) ;
docsrc . load_classes ( index_path ) ;
checked_paths . insert ( index_path ) ;
2017-09-13 09:13:23 +02:00
print_line ( " Loading docs from: " + index_path ) ;
2017-09-12 22:42:36 +02:00
print_line ( " Merging docs.. " ) ;
doc . merge_from ( docsrc ) ;
2017-09-13 09:13:23 +02:00
for ( Set < String > : : Element * E = checked_paths . front ( ) ; E ; E = E - > next ( ) ) {
print_line ( " Erasing old docs at: " + E - > get ( ) ) ;
2017-09-12 22:42:36 +02:00
DocData : : erase_classes ( E - > get ( ) ) ;
2016-12-16 12:12:22 +01:00
}
2017-09-12 22:42:36 +02:00
print_line ( " Generating new docs.. " ) ;
2017-09-13 09:13:23 +02:00
doc . save_classes ( index_path , doc_data_classes ) ;
2014-02-10 02:10:30 +01:00
return false ;
}
# endif
2017-08-14 15:15:06 +02:00
if ( _export_preset ! = " " ) {
2017-03-05 16:44:50 +01:00
if ( game_path = = " " ) {
String err = " Command line param " ;
2017-06-21 11:09:30 +02:00
err + = export_debug ? " --export-debug " : " --export " ;
2017-03-05 16:44:50 +01:00
err + = " passed but no destination path given. \n " ;
err + = " Please specify the binary's file path to export to. Aborting export. " ;
2015-11-26 21:59:25 +01:00
ERR_PRINT ( err . utf8 ( ) . get_data ( ) ) ;
return false ;
}
}
2017-07-18 02:05:38 +02:00
if ( script = = " " & & game_path = = " " & & String ( GLOBAL_DEF ( " application/run/main_scene " , " " ) ) ! = " " ) {
game_path = GLOBAL_DEF ( " application/run/main_scene " , " " ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
MainLoop * main_loop = NULL ;
2014-02-10 02:10:30 +01:00
if ( editor ) {
2014-11-06 01:20:42 +01:00
main_loop = memnew ( SceneTree ) ;
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
if ( test ! = " " ) {
2014-02-10 02:10:30 +01:00
# ifdef DEBUG_ENABLED
2017-03-05 16:44:50 +01:00
main_loop = test_main ( test , args ) ;
2014-02-10 02:10:30 +01:00
if ( ! main_loop )
return false ;
# endif
2017-03-05 16:44:50 +01:00
} else if ( script ! = " " ) {
2014-02-10 02:10:30 +01:00
Ref < Script > script_res = ResourceLoader : : load ( script ) ;
2017-03-05 16:44:50 +01:00
ERR_EXPLAIN ( " Can't load script: " + script ) ;
ERR_FAIL_COND_V ( script_res . is_null ( ) , false ) ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
if ( script_res - > can_instance ( ) /*&& script_res->inherits_from("SceneTreeScripted")*/ ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
StringName instance_type = script_res - > get_instance_base_type ( ) ;
2017-01-03 03:03:46 +01:00
Object * obj = ClassDB : : instance ( instance_type ) ;
2017-08-24 22:58:51 +02:00
MainLoop * script_loop = Object : : cast_to < MainLoop > ( obj ) ;
2014-02-10 02:10:30 +01:00
if ( ! script_loop ) {
if ( obj )
memdelete ( obj ) ;
2017-03-05 16:44:50 +01:00
ERR_EXPLAIN ( " Can't load script ' " + script + " ', it does not inherit from a MainLoop type " ) ;
ERR_FAIL_COND_V ( ! script_loop , false ) ;
2014-02-10 02:10:30 +01:00
}
script_loop - > set_init_script ( script_res ) ;
2017-03-05 16:44:50 +01:00
main_loop = script_loop ;
2014-02-10 02:10:30 +01:00
} else {
return false ;
}
} else {
2017-07-18 02:05:38 +02:00
main_loop_type = GLOBAL_DEF ( " application/run/main_loop_type " , " " ) ;
2014-02-10 02:10:30 +01:00
}
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
if ( ! main_loop & & main_loop_type = = " " )
main_loop_type = " SceneTree " ;
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
if ( ! main_loop ) {
2017-01-03 03:03:46 +01:00
if ( ! ClassDB : : class_exists ( main_loop_type ) ) {
2017-08-19 16:45:03 +02:00
OS : : get_singleton ( ) - > alert ( " Error: MainLoop type doesn't exist: " + main_loop_type ) ;
2014-02-10 02:10:30 +01:00
return false ;
} else {
2017-01-03 03:03:46 +01:00
Object * ml = ClassDB : : instance ( main_loop_type ) ;
2014-02-10 02:10:30 +01:00
if ( ! ml ) {
ERR_EXPLAIN ( " Can't instance MainLoop type " ) ;
ERR_FAIL_V ( false ) ;
}
2017-08-24 22:58:51 +02:00
main_loop = Object : : cast_to < MainLoop > ( ml ) ;
2014-02-10 02:10:30 +01:00
if ( ! main_loop ) {
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
memdelete ( ml ) ;
ERR_EXPLAIN ( " Invalid MainLoop type " ) ;
ERR_FAIL_V ( false ) ;
}
}
}
2017-01-03 03:03:46 +01:00
if ( main_loop - > is_class ( " SceneTree " ) ) {
2016-03-09 00:00:52 +01:00
2017-08-24 22:58:51 +02:00
SceneTree * sml = Object : : cast_to < SceneTree > ( main_loop ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 16:17:16 +02:00
# ifdef DEBUG_ENABLED
2015-09-19 04:10:58 +02:00
if ( debug_collisions ) {
sml - > set_debug_collisions_hint ( true ) ;
}
2015-09-20 18:03:46 +02:00
if ( debug_navigation ) {
sml - > set_debug_navigation_hint ( true ) ;
}
2017-04-07 16:17:16 +02:00
# endif
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
EditorNode * editor_node = NULL ;
2014-02-10 02:10:30 +01:00
if ( editor ) {
2017-03-05 16:44:50 +01:00
editor_node = memnew ( EditorNode ) ;
2014-02-10 02:10:30 +01:00
sml - > get_root ( ) - > add_child ( editor_node ) ;
//root_node->set_editor(editor);
//startup editor
2017-08-14 15:15:06 +02:00
if ( _export_preset ! = " " ) {
2014-02-10 02:10:30 +01:00
2017-08-14 15:15:06 +02:00
editor_node - > export_preset ( _export_preset , game_path , export_debug , " " , true ) ;
2017-03-05 16:44:50 +01:00
game_path = " " ; //no load anything
2014-02-10 02:10:30 +01:00
}
}
# endif
2017-07-18 02:05:38 +02:00
{
}
2014-02-10 02:10:30 +01:00
if ( ! editor ) {
//standard helpers that can be changed from main config
2017-07-18 02:05:38 +02:00
String stretch_mode = GLOBAL_DEF ( " display/window/stretch/mode " , " disabled " ) ;
String stretch_aspect = GLOBAL_DEF ( " display/window/stretch/aspect " , " ignore " ) ;
Size2i stretch_size = Size2 ( GLOBAL_DEF ( " display/window/size/width " , 0 ) , GLOBAL_DEF ( " display/window/size/height " , 0 ) ) ;
2017-10-19 16:12:46 +02:00
real_t stretch_shrink = GLOBAL_DEF ( " display/window/stretch/shrink " , 1.0f ) ;
2014-04-15 03:43:44 +02:00
2017-03-05 16:44:50 +01:00
SceneTree : : StretchMode sml_sm = SceneTree : : STRETCH_MODE_DISABLED ;
if ( stretch_mode = = " 2d " )
sml_sm = SceneTree : : STRETCH_MODE_2D ;
else if ( stretch_mode = = " viewport " )
sml_sm = SceneTree : : STRETCH_MODE_VIEWPORT ;
2014-04-15 03:43:44 +02:00
2017-03-05 16:44:50 +01:00
SceneTree : : StretchAspect sml_aspect = SceneTree : : STRETCH_ASPECT_IGNORE ;
if ( stretch_aspect = = " keep " )
sml_aspect = SceneTree : : STRETCH_ASPECT_KEEP ;
else if ( stretch_aspect = = " keep_width " )
sml_aspect = SceneTree : : STRETCH_ASPECT_KEEP_WIDTH ;
else if ( stretch_aspect = = " keep_height " )
sml_aspect = SceneTree : : STRETCH_ASPECT_KEEP_HEIGHT ;
2017-08-09 09:53:38 +02:00
else if ( stretch_aspect = = " expand " )
sml_aspect = SceneTree : : STRETCH_ASPECT_EXPAND ;
2014-04-15 03:43:44 +02:00
2017-07-22 19:07:38 +02:00
sml - > set_screen_stretch ( sml_sm , sml_aspect , stretch_size , stretch_shrink ) ;
2014-02-10 02:10:30 +01:00
2017-07-18 02:05:38 +02:00
sml - > set_auto_accept_quit ( GLOBAL_DEF ( " application/config/auto_accept_quit " , true ) ) ;
sml - > set_quit_on_go_back ( GLOBAL_DEF ( " application/config/quit_on_go_back " , true ) ) ;
2017-07-19 22:00:46 +02:00
String appname = ProjectSettings : : get_singleton ( ) - > get ( " application/config/name " ) ;
2014-02-10 02:10:30 +01:00
appname = TranslationServer : : get_singleton ( ) - > translate ( appname ) ;
OS : : get_singleton ( ) - > set_window_title ( appname ) ;
2017-07-18 02:05:38 +02:00
int shadow_atlas_size = GLOBAL_GET ( " rendering/quality/shadow_atlas/size " ) ;
int shadow_atlas_q0_subdiv = GLOBAL_GET ( " rendering/quality/shadow_atlas/quadrant_0_subdiv " ) ;
int shadow_atlas_q1_subdiv = GLOBAL_GET ( " rendering/quality/shadow_atlas/quadrant_1_subdiv " ) ;
int shadow_atlas_q2_subdiv = GLOBAL_GET ( " rendering/quality/shadow_atlas/quadrant_2_subdiv " ) ;
int shadow_atlas_q3_subdiv = GLOBAL_GET ( " rendering/quality/shadow_atlas/quadrant_3_subdiv " ) ;
2016-11-10 03:55:06 +01:00
sml - > get_root ( ) - > set_shadow_atlas_size ( shadow_atlas_size ) ;
2017-03-05 16:44:50 +01:00
sml - > get_root ( ) - > set_shadow_atlas_quadrant_subdiv ( 0 , Viewport : : ShadowAtlasQuadrantSubdiv ( shadow_atlas_q0_subdiv ) ) ;
sml - > get_root ( ) - > set_shadow_atlas_quadrant_subdiv ( 1 , Viewport : : ShadowAtlasQuadrantSubdiv ( shadow_atlas_q1_subdiv ) ) ;
sml - > get_root ( ) - > set_shadow_atlas_quadrant_subdiv ( 2 , Viewport : : ShadowAtlasQuadrantSubdiv ( shadow_atlas_q2_subdiv ) ) ;
sml - > get_root ( ) - > set_shadow_atlas_quadrant_subdiv ( 3 , Viewport : : ShadowAtlasQuadrantSubdiv ( shadow_atlas_q3_subdiv ) ) ;
2017-07-19 22:00:46 +02:00
Viewport : : Usage usage = Viewport : : Usage ( int ( GLOBAL_GET ( " rendering/quality/intended_usage/framebuffer_allocation " ) ) ) ;
sml - > get_root ( ) - > set_usage ( usage ) ;
2014-02-10 02:10:30 +01:00
2017-09-07 16:22:07 +02:00
bool snap_controls = GLOBAL_DEF ( " gui/common/snap_controls_to_pixels " , true ) ;
sml - > get_root ( ) - > set_snap_controls_to_pixels ( snap_controls ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-07-18 02:05:38 +02:00
GLOBAL_DEF ( " display/window/stretch/mode " , " disabled " ) ;
2017-07-19 22:00:46 +02:00
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " display/window/stretch/mode " , PropertyInfo ( Variant : : STRING , " display/window/stretch/mode " , PROPERTY_HINT_ENUM , " disabled,2d,viewport " ) ) ;
2017-07-18 02:05:38 +02:00
GLOBAL_DEF ( " display/window/stretch/aspect " , " ignore " ) ;
2017-08-09 09:53:38 +02:00
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " display/window/stretch/aspect " , PropertyInfo ( Variant : : STRING , " display/window/stretch/aspect " , PROPERTY_HINT_ENUM , " ignore,keep,keep_width,keep_height,expand " ) ) ;
2017-07-22 19:07:38 +02:00
GLOBAL_DEF ( " display/window/stretch/shrink " , 1 ) ;
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " display/window/stretch/shrink " , PropertyInfo ( Variant : : STRING , " display/window/stretch/shrink " , PROPERTY_HINT_RANGE , " 1,8,1 " ) ) ;
2017-07-18 02:05:38 +02:00
sml - > set_auto_accept_quit ( GLOBAL_DEF ( " application/config/auto_accept_quit " , true ) ) ;
sml - > set_quit_on_go_back ( GLOBAL_DEF ( " application/config/quit_on_go_back " , true ) ) ;
2017-09-07 16:22:07 +02:00
GLOBAL_DEF ( " gui/common/snap_controls_to_pixels " , true ) ;
2014-02-10 02:10:30 +01:00
}
2016-09-06 18:45:35 +02:00
String local_game_path ;
2017-03-05 16:44:50 +01:00
if ( game_path ! = " " & & ! project_manager_request ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
local_game_path = game_path . replace ( " \\ " , " / " ) ;
2014-02-10 02:10:30 +01:00
if ( ! local_game_path . begins_with ( " res:// " ) ) {
2017-03-05 16:44:50 +01:00
bool absolute = ( local_game_path . size ( ) > 1 ) & & ( local_game_path [ 0 ] = = ' / ' | | local_game_path [ 1 ] = = ' : ' ) ;
2014-02-10 02:10:30 +01:00
if ( ! absolute ) {
2017-07-19 22:00:46 +02:00
if ( ProjectSettings : : get_singleton ( ) - > is_using_datapack ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
local_game_path = " res:// " + local_game_path ;
2014-02-10 02:10:30 +01:00
2014-02-19 15:57:14 +01:00
} else {
2017-03-05 16:44:50 +01:00
int sep = local_game_path . find_last ( " / " ) ;
2014-02-19 15:57:14 +01:00
2017-03-05 16:44:50 +01:00
if ( sep = = - 1 ) {
2014-02-19 15:57:14 +01:00
DirAccess * da = DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ;
2017-03-05 16:44:50 +01:00
local_game_path = da - > get_current_dir ( ) + " / " + local_game_path ;
memdelete ( da ) ;
2014-02-19 15:57:14 +01:00
} else {
2017-03-05 16:44:50 +01:00
DirAccess * da = DirAccess : : open ( local_game_path . substr ( 0 , sep ) ) ;
2014-02-19 15:57:14 +01:00
if ( da ) {
2017-03-05 16:44:50 +01:00
local_game_path = da - > get_current_dir ( ) + " / " + local_game_path . substr ( sep + 1 , local_game_path . length ( ) ) ;
2014-02-19 15:57:14 +01:00
memdelete ( da ) ;
}
2014-02-10 02:10:30 +01:00
}
}
}
}
2017-07-19 22:00:46 +02:00
local_game_path = ProjectSettings : : get_singleton ( ) - > localize_path ( local_game_path ) ;
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
if ( editor ) {
2017-08-19 16:45:03 +02:00
Error serr = editor_node - > load_scene ( local_game_path ) ;
2017-09-02 22:32:31 +02:00
if ( serr ! = OK )
ERR_PRINT ( " Failed to load scene " ) ;
2016-01-27 21:53:37 +01:00
OS : : get_singleton ( ) - > set_context ( OS : : CONTEXT_EDITOR ) ;
2016-09-06 18:45:35 +02:00
}
2014-02-10 02:10:30 +01:00
# endif
2016-09-06 18:45:35 +02:00
}
2014-02-10 02:10:30 +01:00
2016-09-06 18:45:35 +02:00
if ( ! project_manager_request & & ! editor ) {
2017-03-05 16:44:50 +01:00
if ( game_path ! = " " | | script ! = " " ) {
2016-09-06 18:45:35 +02:00
//autoload
List < PropertyInfo > props ;
2017-07-19 22:00:46 +02:00
ProjectSettings : : get_singleton ( ) - > get_property_list ( & props ) ;
2016-09-06 18:45:35 +02:00
//first pass, add the constants so they exist before any script is loaded
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = props . front ( ) ; E ; E = E - > next ( ) ) {
2016-09-06 18:45:35 +02:00
String s = E - > get ( ) . name ;
if ( ! s . begins_with ( " autoload/ " ) )
continue ;
2017-03-05 16:44:50 +01:00
String name = s . get_slicec ( ' / ' , 1 ) ;
2017-07-19 22:00:46 +02:00
String path = ProjectSettings : : get_singleton ( ) - > get ( s ) ;
2017-03-05 16:44:50 +01:00
bool global_var = false ;
2016-09-06 18:45:35 +02:00
if ( path . begins_with ( " * " ) ) {
2017-03-05 16:44:50 +01:00
global_var = true ;
2016-01-13 12:27:14 +01:00
}
2016-09-06 18:45:35 +02:00
if ( global_var ) {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
ScriptServer : : get_language ( i ) - > add_global_constant ( name , Variant ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2016-09-06 18:45:35 +02:00
}
}
2015-12-28 19:59:20 +01:00
2016-09-06 18:45:35 +02:00
//second pass, load into global constants
2017-03-05 16:44:50 +01:00
List < Node * > to_add ;
for ( List < PropertyInfo > : : Element * E = props . front ( ) ; E ; E = E - > next ( ) ) {
2016-09-06 18:45:35 +02:00
String s = E - > get ( ) . name ;
if ( ! s . begins_with ( " autoload/ " ) )
continue ;
2017-03-05 16:44:50 +01:00
String name = s . get_slicec ( ' / ' , 1 ) ;
2017-07-19 22:00:46 +02:00
String path = ProjectSettings : : get_singleton ( ) - > get ( s ) ;
2017-03-05 16:44:50 +01:00
bool global_var = false ;
2016-09-06 18:45:35 +02:00
if ( path . begins_with ( " * " ) ) {
2017-03-05 16:44:50 +01:00
global_var = true ;
path = path . substr ( 1 , path . length ( ) - 1 ) ;
2016-09-06 18:45:35 +02:00
}
2015-12-28 19:59:20 +01:00
2016-09-06 18:45:35 +02:00
RES res = ResourceLoader : : load ( path ) ;
2017-03-05 16:44:50 +01:00
ERR_EXPLAIN ( " Can't autoload: " + path ) ;
2016-09-06 18:45:35 +02:00
ERR_CONTINUE ( res . is_null ( ) ) ;
2017-03-05 16:44:50 +01:00
Node * n = NULL ;
2017-01-03 03:03:46 +01:00
if ( res - > is_class ( " PackedScene " ) ) {
2016-09-06 18:45:35 +02:00
Ref < PackedScene > ps = res ;
2017-03-05 16:44:50 +01:00
n = ps - > instance ( ) ;
2017-01-03 03:03:46 +01:00
} else if ( res - > is_class ( " Script " ) ) {
2016-09-06 18:45:35 +02:00
Ref < Script > s = res ;
StringName ibt = s - > get_instance_base_type ( ) ;
2017-03-05 16:44:50 +01:00
bool valid_type = ClassDB : : is_parent_class ( ibt , " Node " ) ;
ERR_EXPLAIN ( " Script does not inherit a Node: " + path ) ;
ERR_CONTINUE ( ! valid_type ) ;
2016-09-06 18:45:35 +02:00
2017-01-03 03:03:46 +01:00
Object * obj = ClassDB : : instance ( ibt ) ;
2016-09-06 18:45:35 +02:00
2017-03-05 16:44:50 +01:00
ERR_EXPLAIN ( " Cannot instance script for autoload, expected 'Node' inheritance, got: " + String ( ibt ) ) ;
ERR_CONTINUE ( obj = = NULL ) ;
2016-09-06 18:45:35 +02:00
2017-08-24 22:58:51 +02:00
n = Object : : cast_to < Node > ( obj ) ;
2016-09-06 18:45:35 +02:00
n - > set_script ( s . get_ref_ptr ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
ERR_EXPLAIN ( " Path in autoload not a node or script: " + path ) ;
2016-09-06 18:45:35 +02:00
ERR_CONTINUE ( ! n ) ;
n - > set_name ( name ) ;
//defer so references are all valid on _ready()
to_add . push_back ( n ) ;
2016-01-13 13:10:20 +01:00
2016-09-06 18:45:35 +02:00
if ( global_var ) {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
ScriptServer : : get_language ( i ) - > add_global_constant ( name , n ) ;
2016-09-06 18:45:35 +02:00
}
2016-01-13 13:10:20 +01:00
}
2016-09-06 18:45:35 +02:00
}
2016-01-13 13:10:20 +01:00
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = to_add . front ( ) ; E ; E = E - > next ( ) ) {
2016-01-13 13:10:20 +01:00
2016-09-06 18:45:35 +02:00
sml - > get_root ( ) - > add_child ( E - > get ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2016-09-06 18:45:35 +02:00
//singletons
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( game_path ! = " " ) {
Node * scene = NULL ;
2014-02-10 02:10:30 +01:00
Ref < PackedScene > scenedata = ResourceLoader : : load ( local_game_path ) ;
if ( scenedata . is_valid ( ) )
2017-03-05 16:44:50 +01:00
scene = scenedata - > instance ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ERR_EXPLAIN ( " Failed loading scene: " + local_game_path ) ;
ERR_FAIL_COND_V ( ! scene , false )
2015-05-17 21:33:35 +02:00
sml - > add_current_scene ( scene ) ;
2014-02-10 02:10:30 +01:00
2017-07-18 02:05:38 +02:00
String iconpath = GLOBAL_DEF ( " application/config/icon " , " Variant() " ) ;
2017-03-05 16:44:50 +01:00
if ( iconpath ! = " " ) {
2017-05-17 12:36:47 +02:00
Ref < Image > icon ;
2017-08-11 19:13:17 +02:00
icon . instance ( ) ;
2017-09-15 18:41:11 +02:00
if ( icon - > load ( iconpath ) = = OK ) {
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > set_icon ( icon ) ;
2017-09-15 18:41:11 +02:00
hasicon = true ;
}
2014-02-10 02:10:30 +01:00
}
}
}
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
if ( project_manager_request | | ( script = = " " & & test = = " " & & game_path = = " " & & ! editor ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ProjectManager * pmanager = memnew ( ProjectManager ) ;
ProgressDialog * progress_dialog = memnew ( ProgressDialog ) ;
2016-07-10 22:19:19 +02:00
pmanager - > add_child ( progress_dialog ) ;
2014-02-10 02:10:30 +01:00
sml - > get_root ( ) - > add_child ( pmanager ) ;
2016-01-27 21:53:37 +01:00
OS : : get_singleton ( ) - > set_context ( OS : : CONTEXT_PROJECTMAN ) ;
2014-02-10 02:10:30 +01:00
}
# endif
}
2017-09-15 18:41:11 +02:00
if ( ! hasicon ) {
Ref < Image > icon = memnew ( Image ( app_icon_png ) ) ;
OS : : get_singleton ( ) - > set_icon ( icon ) ;
}
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > set_main_loop ( main_loop ) ;
2014-02-10 02:10:30 +01:00
return true ;
}
2017-03-05 16:44:50 +01:00
uint64_t Main : : last_ticks = 0 ;
uint64_t Main : : target_ticks = 0 ;
float Main : : time_accum = 0 ;
uint32_t Main : : frames = 0 ;
uint32_t Main : : frame = 0 ;
2014-02-10 02:10:30 +01:00
bool Main : : force_redraw_requested = false ;
2016-05-22 02:18:16 +02:00
//for performance metrics
2017-09-30 16:19:07 +02:00
static uint64_t physics_process_max = 0 ;
2017-03-05 16:44:50 +01:00
static uint64_t idle_process_max = 0 ;
2014-02-10 02:10:30 +01:00
bool Main : : iteration ( ) {
2017-03-05 16:44:50 +01:00
uint64_t ticks = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2017-07-15 06:23:10 +02:00
Engine : : get_singleton ( ) - > _frame_ticks = ticks ;
2017-03-05 16:44:50 +01:00
uint64_t ticks_elapsed = ticks - last_ticks ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
double step = ( double ) ticks_elapsed / 1000000.0 ;
2017-08-30 12:40:35 +02:00
if ( fixed_fps ! = - 1 )
step = 1.0 / fixed_fps ;
2017-03-05 16:44:50 +01:00
float frame_slice = 1.0 / Engine : : get_singleton ( ) - > get_iterations_per_second ( ) ;
2015-04-15 03:05:14 +02:00
2017-07-15 06:23:10 +02:00
Engine : : get_singleton ( ) - > _frame_step = step ;
2017-01-14 12:26:56 +01:00
/*
if ( time_accum + step < frame_slice )
return false ;
*/
2016-05-22 02:18:16 +02:00
2017-09-30 16:19:07 +02:00
uint64_t physics_process_ticks = 0 ;
2017-03-05 16:44:50 +01:00
uint64_t idle_process_ticks = 0 ;
2016-05-22 02:18:16 +02:00
2017-03-05 16:44:50 +01:00
frame + = ticks_elapsed ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
last_ticks = ticks ;
2014-02-10 02:10:30 +01:00
2017-08-30 12:40:35 +02:00
if ( fixed_fps = = - 1 & & step > frame_slice * 8 )
2017-03-05 16:44:50 +01:00
step = frame_slice * 8 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
time_accum + = step ;
2014-02-10 02:10:30 +01:00
2017-01-13 16:51:14 +01:00
float time_scale = Engine : : get_singleton ( ) - > get_time_scale ( ) ;
2014-09-21 06:43:42 +02:00
2017-03-05 16:44:50 +01:00
bool exit = false ;
2014-02-10 02:10:30 +01:00
int iters = 0 ;
2017-09-30 16:19:07 +02:00
Engine : : get_singleton ( ) - > _in_physics = true ;
2016-09-01 23:58:52 +02:00
2017-03-05 16:44:50 +01:00
while ( time_accum > frame_slice ) {
2014-02-10 02:10:30 +01:00
2017-10-21 16:28:08 +02:00
uint64_t physics_begin = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2014-02-10 02:10:30 +01:00
PhysicsServer : : get_singleton ( ) - > sync ( ) ;
PhysicsServer : : get_singleton ( ) - > flush_queries ( ) ;
Physics2DServer : : get_singleton ( ) - > sync ( ) ;
Physics2DServer : : get_singleton ( ) - > flush_queries ( ) ;
2017-03-05 16:44:50 +01:00
if ( OS : : get_singleton ( ) - > get_main_loop ( ) - > iteration ( frame_slice * time_scale ) ) {
exit = true ;
2014-02-10 02:10:30 +01:00
break ;
}
message_queue - > flush ( ) ;
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > step ( frame_slice * time_scale ) ;
2015-05-26 06:05:08 +02:00
Physics2DServer : : get_singleton ( ) - > end_sync ( ) ;
2017-03-05 16:44:50 +01:00
Physics2DServer : : get_singleton ( ) - > step ( frame_slice * time_scale ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
time_accum - = frame_slice ;
2014-02-10 02:10:30 +01:00
message_queue - > flush ( ) ;
2017-10-21 16:28:08 +02:00
physics_process_ticks = MAX ( physics_process_ticks , OS : : get_singleton ( ) - > get_ticks_usec ( ) - physics_begin ) ; // keep the largest one for reference
physics_process_max = MAX ( OS : : get_singleton ( ) - > get_ticks_usec ( ) - physics_begin , physics_process_max ) ;
2014-02-10 02:10:30 +01:00
iters + + ;
2017-09-30 16:19:07 +02:00
Engine : : get_singleton ( ) - > _physics_frames + + ;
2014-02-10 02:10:30 +01:00
}
2017-09-30 16:19:07 +02:00
Engine : : get_singleton ( ) - > _in_physics = false ;
2016-09-01 23:58:52 +02:00
2014-02-10 02:10:30 +01:00
uint64_t idle_begin = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > get_main_loop ( ) - > idle ( step * time_scale ) ;
2014-02-10 02:10:30 +01:00
message_queue - > flush ( ) ;
2015-06-07 03:06:58 +02:00
VisualServer : : get_singleton ( ) - > sync ( ) ; //sync if still drawing from previous frames.
2017-08-30 12:40:35 +02:00
if ( OS : : get_singleton ( ) - > can_draw ( ) & & ! disable_render_loop ) {
2014-02-10 02:10:30 +01:00
if ( ( ! force_redraw_requested ) & & OS : : get_singleton ( ) - > is_in_low_processor_usage_mode ( ) ) {
if ( VisualServer : : get_singleton ( ) - > has_changed ( ) ) {
VisualServer : : get_singleton ( ) - > draw ( ) ; // flush visual commands
2017-01-13 16:51:14 +01:00
Engine : : get_singleton ( ) - > frames_drawn + + ;
2014-02-10 02:10:30 +01:00
}
} else {
VisualServer : : get_singleton ( ) - > draw ( ) ; // flush visual commands
2017-01-13 16:51:14 +01:00
Engine : : get_singleton ( ) - > frames_drawn + + ;
2014-02-10 02:10:30 +01:00
force_redraw_requested = false ;
}
}
if ( AudioServer : : get_singleton ( ) )
AudioServer : : get_singleton ( ) - > update ( ) ;
2017-03-05 16:44:50 +01:00
idle_process_ticks = OS : : get_singleton ( ) - > get_ticks_usec ( ) - idle_begin ;
idle_process_max = MAX ( idle_process_ticks , idle_process_max ) ;
2016-05-22 02:18:16 +02:00
uint64_t frame_time = OS : : get_singleton ( ) - > get_ticks_usec ( ) - ticks ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
ScriptServer : : get_language ( i ) - > frame ( ) ;
}
2016-05-22 02:18:16 +02:00
if ( script_debugger ) {
if ( script_debugger - > is_profiling ( ) ) {
2017-09-30 16:19:07 +02:00
script_debugger - > profiling_set_frame_times ( USEC_TO_SEC ( frame_time ) , USEC_TO_SEC ( idle_process_ticks ) , USEC_TO_SEC ( physics_process_ticks ) , frame_slice ) ;
2016-05-22 02:18:16 +02:00
}
2014-02-10 02:10:30 +01:00
script_debugger - > idle_poll ( ) ;
2016-05-22 02:18:16 +02:00
}
2014-02-10 02:10:30 +01:00
frames + + ;
2017-01-13 16:51:14 +01:00
Engine : : get_singleton ( ) - > _idle_frames + + ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( frame > 1000000 ) {
2014-02-10 02:10:30 +01:00
2017-07-18 02:05:38 +02:00
if ( GLOBAL_DEF ( " debug/settings/stdout/print_fps " , OS : : get_singleton ( ) - > is_stdout_verbose ( ) ) ) {
2017-03-05 16:44:50 +01:00
print_line ( " FPS: " + itos ( frames ) ) ;
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
Engine : : get_singleton ( ) - > _fps = frames ;
2016-05-22 02:18:16 +02:00
performance - > set_process_time ( USEC_TO_SEC ( idle_process_max ) ) ;
2017-09-30 16:19:07 +02:00
performance - > set_physics_process_time ( USEC_TO_SEC ( physics_process_max ) ) ;
2017-03-05 16:44:50 +01:00
idle_process_max = 0 ;
2017-09-30 16:19:07 +02:00
physics_process_max = 0 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
frame % = 1000000 ;
frames = 0 ;
2014-02-10 02:10:30 +01:00
}
2017-08-30 12:40:35 +02:00
if ( fixed_fps ! = - 1 )
return exit ;
2014-02-10 02:10:30 +01:00
if ( OS : : get_singleton ( ) - > is_in_low_processor_usage_mode ( ) | | ! OS : : get_singleton ( ) - > can_draw ( ) )
2017-11-22 18:40:43 +01:00
OS : : get_singleton ( ) - > delay_usec ( OS : : get_singleton ( ) - > get_low_processor_usage_mode_sleep_usec ( ) ) ; //apply some delay to force idle time (results in about 60 FPS max)
2014-02-10 02:10:30 +01:00
else {
2017-01-13 16:51:14 +01:00
uint32_t frame_delay = Engine : : get_singleton ( ) - > get_frame_delay ( ) ;
2014-02-10 02:10:30 +01:00
if ( frame_delay )
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > delay_usec ( Engine : : get_singleton ( ) - > get_frame_delay ( ) * 1000 ) ;
2014-02-10 02:10:30 +01:00
}
2017-01-13 16:51:14 +01:00
int target_fps = Engine : : get_singleton ( ) - > get_target_fps ( ) ;
2017-03-05 16:44:50 +01:00
if ( target_fps > 0 ) {
uint64_t time_step = 1000000L / target_fps ;
2014-02-19 16:35:39 +01:00
target_ticks + = time_step ;
uint64_t current_ticks = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2017-03-05 16:44:50 +01:00
if ( current_ticks < target_ticks ) OS : : get_singleton ( ) - > delay_usec ( target_ticks - current_ticks ) ;
2014-02-19 16:35:39 +01:00
current_ticks = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2017-03-05 16:44:50 +01:00
target_ticks = MIN ( MAX ( target_ticks , current_ticks - time_step ) , current_ticks + time_step ) ;
2014-02-19 16:35:39 +01:00
}
2014-02-10 02:10:30 +01:00
return exit ;
}
void Main : : force_redraw ( ) {
force_redraw_requested = true ;
} ;
void Main : : cleanup ( ) {
ERR_FAIL_COND ( ! _start_success ) ;
2016-05-22 02:18:16 +02:00
if ( script_debugger ) {
if ( use_debug_profiler ) {
script_debugger - > profiling_end ( ) ;
}
2014-02-10 02:10:30 +01:00
memdelete ( script_debugger ) ;
2016-05-22 02:18:16 +02:00
}
2014-02-10 02:10:30 +01:00
OS : : get_singleton ( ) - > delete_main_loop ( ) ;
OS : : get_singleton ( ) - > _cmdline . clear ( ) ;
2017-03-05 16:44:50 +01:00
OS : : get_singleton ( ) - > _execpath = " " ;
OS : : get_singleton ( ) - > _local_clipboard = " " ;
2014-02-10 02:10:30 +01:00
2017-07-22 21:11:04 +02:00
ScriptServer : : finish_languages ( ) ;
2017-01-15 20:06:14 +01:00
2014-02-25 13:31:47 +01:00
# ifdef TOOLS_ENABLED
EditorNode : : unregister_editor_types ( ) ;
# endif
2017-07-22 21:11:04 +02:00
if ( audio_server ) {
2017-08-01 23:09:52 +02:00
audio_server - > finish ( ) ;
2017-07-22 21:11:04 +02:00
memdelete ( audio_server ) ;
}
2017-10-07 15:51:17 +02:00
if ( arvr_server ) {
// cleanup now before we pull the rug from underneath...
memdelete ( arvr_server ) ;
}
2016-03-09 00:00:52 +01:00
unregister_driver_types ( ) ;
2014-02-10 02:10:30 +01:00
unregister_module_types ( ) ;
2017-11-16 01:33:48 +01:00
unregister_platform_apis ( ) ;
2016-03-09 00:00:52 +01:00
unregister_scene_types ( ) ;
2014-02-10 02:10:30 +01:00
unregister_server_types ( ) ;
OS : : get_singleton ( ) - > finalize ( ) ;
2017-10-21 13:02:06 +02:00
finalize_physics ( ) ;
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
if ( packed_data )
memdelete ( packed_data ) ;
if ( file_access_network_client )
memdelete ( file_access_network_client ) ;
if ( performance )
memdelete ( performance ) ;
if ( input_map )
memdelete ( input_map ) ;
if ( translation_server )
2017-03-05 16:44:50 +01:00
memdelete ( translation_server ) ;
2014-02-10 02:10:30 +01:00
if ( globals )
memdelete ( globals ) ;
2017-01-13 16:51:14 +01:00
if ( engine )
memdelete ( engine ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
memdelete ( message_queue ) ;
2014-02-10 02:10:30 +01:00
unregister_core_driver_types ( ) ;
unregister_core_types ( ) ;
OS : : get_singleton ( ) - > clear_last_error ( ) ;
OS : : get_singleton ( ) - > finalize_core ( ) ;
}