diff options
Diffstat (limited to 'main/main.cpp')
-rw-r--r-- | main/main.cpp | 309 |
1 files changed, 180 insertions, 129 deletions
diff --git a/main/main.cpp b/main/main.cpp index f9044b61cd..f4665c4ad4 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -30,6 +30,7 @@ #include "main.h" +#include "core/crypto/crypto.h" #include "core/input_map.h" #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" @@ -37,8 +38,6 @@ #include "core/io/image_loader.h" #include "core/io/ip.h" #include "core/io/resource_loader.h" -#include "core/io/stream_peer_ssl.h" -#include "core/io/stream_peer_tcp.h" #include "core/message_queue.h" #include "core/os/dir_access.h" #include "core/os/os.h" @@ -53,11 +52,11 @@ #include "drivers/register_driver_types.h" #include "main/app_icon.gen.h" #include "main/input_default.h" +#include "main/main_timer_sync.h" #include "main/performance.h" #include "main/splash.gen.h" #include "main/splash_editor.gen.h" #include "main/tests/test_main.h" -#include "main/timer_sync.h" #include "modules/register_module_types.h" #include "platform/register_platform_apis.h" #include "scene/main/scene_tree.h" @@ -161,7 +160,7 @@ static String unescape_cmdline(const String &p_str) { static String get_full_version_string() { String hash = String(VERSION_HASH); if (hash.length() != 0) - hash = "." + hash.left(7); + hash = "." + hash.left(9); return String(VERSION_FULL_BUILD) + hash; } @@ -204,7 +203,8 @@ void finalize_physics() { void Main::print_help(const char *p_binary) { - print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - https://godotengine.org"); + print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); + OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n"); OS::get_singleton()->print("(c) 2007-2019 Juan Linietsky, Ariel Manzur.\n"); OS::get_singleton()->print("(c) 2014-2019 Godot Engine contributors.\n"); OS::get_singleton()->print("\n"); @@ -247,6 +247,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(").\n"); OS::get_singleton()->print("\n"); +#ifndef SERVER_ENABLED 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"); @@ -257,14 +258,15 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n"); OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n"); OS::get_singleton()->print("\n"); +#endif OS::get_singleton()->print("Debug options:\n"); OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n"); OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n"); OS::get_singleton()->print(" --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"); +#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED) + OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n"); OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n"); #endif OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n"); @@ -372,7 +374,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph while (I) { - I->get() = unescape_cmdline(I->get().strip_escapes()); + I->get() = unescape_cmdline(I->get().strip_edges()); I = I->next(); } @@ -394,7 +396,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Vector<String> breakpoints; bool use_custom_res = true; bool force_res = false; +#ifdef TOOLS_ENABLED bool found_project = false; +#endif packed_data = PackedData::get_singleton(); if (!packed_data) @@ -427,6 +431,49 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph print_line(get_full_version_string()); goto error; + } else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output + + OS::get_singleton()->_verbose_stdout = true; + } else if (I->get() == "--quiet") { // quieter output + + quiet_stdout = true; + + } else if (I->get() == "--audio-driver") { // audio driver + + if (I->next()) { + + audio_driver = I->next()->get(); + N = I->next()->next(); + } else { + OS::get_singleton()->print("Missing audio driver argument, aborting.\n"); + goto error; + } + + } else if (I->get() == "--video-driver") { // force video driver + + if (I->next()) { + + video_driver = I->next()->get(); + N = I->next()->next(); + } else { + OS::get_singleton()->print("Missing video driver argument, aborting.\n"); + goto error; + } +#ifndef SERVER_ENABLED + } else if (I->get() == "-f" || I->get() == "--fullscreen") { // force fullscreen + + init_fullscreen = true; + } else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window + + init_maximized = true; + video_mode.maximized = true; + + } else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window + + init_windowed = true; + } else if (I->get() == "-t" || I->get() == "--always-on-top") { // force always-on-top window + + init_always_on_top = true; } else if (I->get() == "--resolution") { // force resolution if (I->next()) { @@ -457,6 +504,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing resolution argument, aborting.\n"); goto error; } + } else if (I->get() == "--position") { // set window position if (I->next()) { @@ -481,29 +529,17 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window - - init_maximized = true; - video_mode.maximized = true; - } else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window + } else if (I->get() == "--low-dpi") { // force low DPI (macOS only) - init_windowed = true; - } else if (I->get() == "-t" || I->get() == "--always-on-top") { // force always-on-top window + force_lowdpi = true; + } else if (I->get() == "--no-window") { // disable window creation (Windows only) - init_always_on_top = true; + OS::get_singleton()->set_no_window_mode(true); +#endif } else if (I->get() == "--profiling") { // enable profiling use_debug_profiler = true; - } else if (I->get() == "--video-driver") { // force video driver - if (I->next()) { - - video_driver = I->next()->get(); - N = I->next()->next(); - } else { - OS::get_singleton()->print("Missing video driver argument, aborting.\n"); - goto error; - } } else if (I->get() == "-l" || I->get() == "--language") { // language if (I->next()) { @@ -514,9 +550,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing language argument, aborting.\n"); goto error; } - } else if (I->get() == "--low-dpi") { // force low DPI (macOS only) - force_lowdpi = true; } else if (I->get() == "--remote-fs") { // remote filesystem if (I->next()) { @@ -553,22 +587,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing render thread mode argument, aborting.\n"); goto error; } - - } else if (I->get() == "--audio-driver") { // audio driver - - if (I->next()) { - - audio_driver = I->next()->get(); - N = I->next()->next(); - } else { - OS::get_singleton()->print("Missing audio driver argument, aborting.\n"); - goto error; - } - - } else if (I->get() == "-f" || I->get() == "--fullscreen") { // force fullscreen - - //video_mode.fullscreen=false; - init_fullscreen = true; #ifdef TOOLS_ENABLED } else if (I->get() == "-e" || I->get() == "--editor") { // starts editor @@ -580,15 +598,19 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph auto_build_solutions = true; editor = true; -#endif - } else if (I->get() == "--no-window") { // disable window creation, Windows only +#ifdef DEBUG_METHODS_ENABLED + } else if (I->get() == "--gdnative-generate-json-api") { + // Register as an editor instance to use the GLES2 fallback automatically on hardware that doesn't support the GLES3 backend + editor = true; - OS::get_singleton()->set_no_window_mode(true); - } else if (I->get() == "--quiet") { // quieter output + // We still pass it to the main arguments since the argument handling itself is not done in this function + main_args.push_back(I->get()); +#endif + } else if (I->get() == "--export" || I->get() == "--export-debug") { // Export project - quiet_stdout = true; - } else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output - OS::get_singleton()->_verbose_stdout = true; + editor = true; + main_args.push_back(I->get()); +#endif } else if (I->get() == "--path") { // set path of project to start or edit if (I->next()) { @@ -672,7 +694,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "-d" || I->get() == "--debug") { debug_mode = "local"; -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED) } else if (I->get() == "--debug-collisions") { debug_collisions = true; } else if (I->get() == "--debug-navigation") { @@ -746,14 +768,16 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } if (globals->setup(project_path, main_pack, upwards) == OK) { +#ifdef TOOLS_ENABLED found_project = true; +#endif } else { #ifdef TOOLS_ENABLED editor = false; #else String error_msg = "Error: Could not load game data at path '" + project_path + "'. Is the .pck file missing?\n"; - OS::get_singleton()->print(error_msg.ascii().get_data()); + OS::get_singleton()->print("%s", error_msg.ascii().get_data()); OS::get_singleton()->alert(error_msg); goto error; @@ -766,8 +790,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_chars_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_chars_per_second", PROPERTY_HINT_RANGE, "0, 4096, 1, or_greater")); GLOBAL_DEF("network/limits/debugger_stdout/max_messages_per_frame", 10); ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_messages_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_messages_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater")); - GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_frame", 10); - ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater")); + GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_second", 100); + ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater")); + GLOBAL_DEF("network/limits/debugger_stdout/max_warnings_per_second", 100); + ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_warnings_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_warnings_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater")); if (debug_mode == "remote") { @@ -784,7 +810,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph memdelete(sdr); } else { script_debugger = sdr; - sdr->set_allow_focus_steal_pid(allow_focus_steal_pid); } } else if (debug_mode == "local") { @@ -798,10 +823,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph String bp = breakpoints[i]; int sp = bp.find_last(":"); - if (sp == -1) { - ERR_EXPLAIN("Invalid breakpoint: '" + bp + "', expected file:line format."); - ERR_CONTINUE(sp == -1); - } + ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format."); script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp)); } @@ -853,6 +875,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } if (editor || project_manager) { + Engine::get_singleton()->set_editor_hint(true); use_custom_res = false; input_map->load_default(); //keys for editor } else { @@ -877,8 +900,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph video_driver = GLOBAL_GET("rendering/quality/driver/driver_name"); } - GLOBAL_DEF("rendering/quality/driver/driver_fallback", "Best"); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_fallback", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_fallback", PROPERTY_HINT_ENUM, "Best,Never")); + GLOBAL_DEF("rendering/quality/driver/fallback_to_gles2", false); // Assigning here even though it's GLES2-specific, to be sure that it appears in docs GLOBAL_DEF("rendering/quality/2d/gles2_use_nvidia_rect_flicker_workaround", false); @@ -922,13 +944,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false); } - OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/allow_per_pixel_transparency", false); - - video_mode.use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", true); + video_mode.use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true); OS::get_singleton()->_use_vsync = video_mode.use_vsync; - video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency", false); - video_mode.layered_splash = GLOBAL_DEF("display/window/per_pixel_transparency_splash", false); + OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false); + video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false); GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2); GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3); @@ -1010,6 +1030,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_fps", PropertyInfo(Variant::INT, "physics/common/physics_fps", PROPERTY_HINT_RANGE, "1,120,1,or_greater")); Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5)); Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0)); ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,120,1,or_greater")); @@ -1025,7 +1046,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } 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)); + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(GLOBAL_DEF("application/run/low_processor_mode_sleep_usec", 6900)); // Roughly 144 FPS ProjectSettings::get_singleton()->set_custom_property_info("application/run/low_processor_mode_sleep_usec", PropertyInfo(Variant::INT, "application/run/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "0,33200,1,or_greater")); // No negative numbers Engine::get_singleton()->set_frame_delay(frame_delay); @@ -1081,6 +1102,9 @@ error: Error Main::setup2(Thread::ID p_main_tid_override) { + // Print engine name and version + print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); + if (p_main_tid_override) { Thread::_main_thread_id = p_main_tid_override; } @@ -1090,6 +1114,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) { return err; } + print_line(" "); //add a blank line for readability + if (init_use_custom_pos) { OS::get_singleton()->set_window_position(init_custom_pos); } @@ -1126,6 +1152,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) { OS::get_singleton()->set_window_always_on_top(true); } + if (allow_focus_steal_pid) { + OS::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid); + } + register_server_types(); MAIN_PRINT("Main: Load Remaps"); @@ -1136,6 +1166,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { if (show_logo) { //boot logo! String boot_logo_path = GLOBAL_DEF("application/boot_splash/image", String()); bool boot_logo_scale = GLOBAL_DEF("application/boot_splash/fullsize", true); + bool boot_logo_filter = GLOBAL_DEF("application/boot_splash/use_filter", true); ProjectSettings::get_singleton()->set_custom_property_info("application/boot_splash/image", PropertyInfo(Variant::STRING, "application/boot_splash/image", PROPERTY_HINT_FILE, "*.png")); Ref<Image> boot_logo; @@ -1144,15 +1175,15 @@ Error Main::setup2(Thread::ID p_main_tid_override) { if (boot_logo_path != String()) { boot_logo.instance(); - Error err = ImageLoader::load_image(boot_logo_path, boot_logo); - if (err) + Error load_err = ImageLoader::load_image(boot_logo_path, boot_logo); + if (load_err) ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash."); } Color boot_bg_color = GLOBAL_DEF("application/boot_splash/bg_color", boot_splash_bg_color); if (boot_logo.is_valid()) { OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec(); - VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale); + VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale, boot_logo_filter); } else { #ifndef NO_DEFAULT_BOOT_LOGO @@ -1183,6 +1214,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) { GLOBAL_DEF("application/config/icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp")); + GLOBAL_DEF("application/config/macos_native_icon", String()); + ProjectSettings::get_singleton()->set_custom_property_info("application/config/macos_native_icon", PropertyInfo(Variant::STRING, "application/config/macos_native_icon", PROPERTY_HINT_FILE, "*.icns")); + + GLOBAL_DEF("application/config/windows_native_icon", String()); + ProjectSettings::get_singleton()->set_custom_property_info("application/config/windows_native_icon", PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico")); + InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton()); if (id) { if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) { @@ -1203,6 +1240,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { GLOBAL_DEF("display/mouse_cursor/custom_image", String()); GLOBAL_DEF("display/mouse_cursor/custom_image_hotspot", Vector2()); + GLOBAL_DEF("display/mouse_cursor/tooltip_position_offset", Point2(10, 10)); 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")); if (String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image")) != String()) { @@ -1273,7 +1311,9 @@ bool Main::start() { bool hasicon = false; String doc_tool; List<String> removal_docs; +#ifdef TOOLS_ENABLED bool doc_base = true; +#endif String game_path; String script; String test; @@ -1286,9 +1326,11 @@ bool Main::start() { List<String> args = OS::get_singleton()->get_cmdline_args(); for (int i = 0; i < args.size(); i++) { //parameters that do not have an argument to the right - if (args[i] == "--no-docbase") { - doc_base = false; + if (args[i] == "--check-only") { + check_only = true; #ifdef TOOLS_ENABLED + } else if (args[i] == "--no-docbase") { + doc_base = false; } else if (args[i] == "-e" || args[i] == "--editor") { editor = true; } else if (args[i] == "-p" || args[i] == "--project-manager") { @@ -1296,8 +1338,6 @@ bool Main::start() { #endif } else if (args[i].length() && args[i][0] != '-' && game_path == "") { game_path = args[i]; - } else if (args[i] == "--check-only") { - check_only = true; } //parameters that have an argument to the right else if (i < (args.size() - 1)) { @@ -1313,20 +1353,10 @@ bool Main::start() { removal_docs.push_back(args[j]); } else if (args[i] == "--export") { editor = true; //needs editor - if (i + 1 < args.size()) { - _export_preset = args[i + 1]; - } else { - ERR_PRINT("Export preset name not specified"); - return false; - } + _export_preset = args[i + 1]; } else if (args[i] == "--export-debug") { editor = true; //needs editor - if (i + 1 < args.size()) { - _export_preset = args[i + 1]; - } else { - ERR_PRINT("Export preset name not specified"); - return false; - } + _export_preset = args[i + 1]; export_debug = true; #endif } else { @@ -1345,12 +1375,11 @@ bool Main::start() { #ifdef TOOLS_ENABLED if (doc_tool != "") { + Engine::get_singleton()->set_editor_hint(true); // Needed to instance editor-only classes for their default values + { 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); - } + ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory."); } DocData doc; doc.generate(doc_base); @@ -1366,12 +1395,23 @@ bool Main::start() { doc_data_classes[name] = path; if (!checked_paths.has(path)) { checked_paths.insert(path); + + // Create the module documentation directory if it doesn't exist + DirAccess *da = DirAccess::create_for_path(path); + da->make_dir_recursive(path); + memdelete(da); + docsrc.load_classes(path); print_line("Loading docs from: " + path); } } String index_path = doc_tool.plus_file("doc/classes"); + // Create the main documentation directory if it doesn't exist + DirAccess *da = DirAccess::create_for_path(index_path); + da->make_dir_recursive(index_path); + memdelete(da); + docsrc.load_classes(index_path); checked_paths.insert(index_path); print_line("Loading docs from: " + index_path); @@ -1423,8 +1463,7 @@ bool Main::start() { } else if (script != "") { Ref<Script> script_res = ResourceLoader::load(script); - ERR_EXPLAIN("Can't load script: " + script); - ERR_FAIL_COND_V(script_res.is_null(), false); + ERR_FAIL_COND_V_MSG(script_res.is_null(), false, "Can't load script: " + script); if (check_only) { return false; @@ -1438,8 +1477,7 @@ bool Main::start() { if (!script_loop) { if (obj) memdelete(obj); - ERR_EXPLAIN("Can't load script '" + script + "', it does not inherit from a MainLoop type"); - ERR_FAIL_COND_V(!script_loop, false); + ERR_FAIL_V_MSG(false, "Can't load script '" + script + "', it does not inherit from a MainLoop type."); } script_loop->set_init_script(script_res); @@ -1463,17 +1501,13 @@ bool Main::start() { } else { Object *ml = ClassDB::instance(main_loop_type); - if (!ml) { - ERR_EXPLAIN("Can't instance MainLoop type"); - ERR_FAIL_V(false); - } + ERR_FAIL_COND_V_MSG(!ml, false, "Can't instance MainLoop type."); main_loop = Object::cast_to<MainLoop>(ml); if (!main_loop) { memdelete(ml); - ERR_EXPLAIN("Invalid MainLoop type"); - ERR_FAIL_V(false); + ERR_FAIL_V_MSG(false, "Invalid MainLoop type."); } } } @@ -1536,30 +1570,26 @@ bool Main::start() { } RES res = ResourceLoader::load(path); - ERR_EXPLAIN("Can't autoload: " + path); - ERR_CONTINUE(res.is_null()); + ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + path); Node *n = NULL; if (res->is_class("PackedScene")) { Ref<PackedScene> ps = res; n = ps->instance(); } else if (res->is_class("Script")) { - Ref<Script> s = res; - StringName ibt = s->get_instance_base_type(); + Ref<Script> script_res = res; + StringName ibt = script_res->get_instance_base_type(); bool valid_type = ClassDB::is_parent_class(ibt, "Node"); - ERR_EXPLAIN("Script does not inherit a Node: " + path); - ERR_CONTINUE(!valid_type); + ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + path); Object *obj = ClassDB::instance(ibt); - ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt)); - ERR_CONTINUE(obj == NULL); + ERR_CONTINUE_MSG(obj == NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt)); n = Object::cast_to<Node>(obj); - n->set_script(s.get_ref_ptr()); + n->set_script(script_res.get_ref_ptr()); } - ERR_EXPLAIN("Path in autoload not a node or script: " + path); - ERR_CONTINUE(!n); + ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + path); n->set_name(name); //defer so references are all valid on _ready() @@ -1604,7 +1634,7 @@ bool Main::start() { 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)); - real_t stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1.0f); + real_t stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1.0); SceneTree::StretchMode sml_sm = SceneTree::STRETCH_MODE_DISABLED; if (stretch_mode == "2d") @@ -1656,8 +1686,8 @@ bool Main::start() { ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport")); GLOBAL_DEF("display/window/stretch/aspect", "ignore"); 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")); - GLOBAL_DEF("display/window/stretch/shrink", 1); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::REAL, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1,8,1")); + GLOBAL_DEF("display/window/stretch/shrink", 1.0); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::REAL, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1.0,8.0,0.1")); 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)); GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); @@ -1683,13 +1713,13 @@ bool Main::start() { if (sep == -1) { DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - local_game_path = da->get_current_dir() + "/" + local_game_path; + local_game_path = da->get_current_dir().plus_file(local_game_path); memdelete(da); } else { DirAccess *da = DirAccess::open(local_game_path.substr(0, sep)); if (da) { - local_game_path = da->get_current_dir() + "/" + local_game_path.substr(sep + 1, local_game_path.length()); + local_game_path = da->get_current_dir().plus_file(local_game_path.substr(sep + 1, local_game_path.length())); memdelete(da); } } @@ -1717,8 +1747,8 @@ bool Main::start() { if (!project_manager && !editor) { // game - // Load SSL Certificates from Project Settings (or builtin) - StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array()); + // Load SSL Certificates from Project Settings (or builtin). + Crypto::load_default_certificates(GLOBAL_DEF("network/ssl/certificates", "")); if (game_path != "") { Node *scene = NULL; @@ -1726,12 +1756,27 @@ bool Main::start() { if (scenedata.is_valid()) scene = scenedata->instance(); - ERR_EXPLAIN("Failed loading scene: " + local_game_path); - ERR_FAIL_COND_V(!scene, false) + ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path); sml->add_current_scene(scene); +#ifdef OSX_ENABLED + String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()"); + if (mac_iconpath != "") { + OS::get_singleton()->set_native_icon(mac_iconpath); + hasicon = true; + } +#endif + +#ifdef WINDOWS_ENABLED + String win_iconpath = GLOBAL_DEF("application/config/windows_native_icon", "Variant()"); + if (win_iconpath != "") { + OS::get_singleton()->set_native_icon(win_iconpath); + hasicon = true; + } +#endif + String iconpath = GLOBAL_DEF("application/config/icon", "Variant()"); - if (iconpath != "") { + if ((iconpath != "") && (!hasicon)) { Ref<Image> icon; icon.instance(); if (ImageLoader::load_image(iconpath, icon) == OK) { @@ -1751,15 +1796,18 @@ bool Main::start() { pmanager->add_child(progress_dialog); sml->get_root()->add_child(pmanager); OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN); + project_manager = true; + } + + if (project_manager || editor) { + // Hide console window if requested (Windows-only). + bool hide_console = EditorSettings::get_singleton()->get_setting("interface/editor/hide_console_window"); + OS::get_singleton()->set_console_visible(!hide_console); } if (project_manager || editor) { // Load SSL Certificates from Editor Settings (or builtin) - String certs = EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String(); - if (certs != "") - StreamPeerSSL::load_certs_from_file(certs); - else - StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array()); + Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String()); } #endif } @@ -1794,7 +1842,7 @@ bool Main::is_iterating() { return iterating > 0; } -// For performance metrics +// For performance metrics. static uint64_t physics_process_max = 0; static uint64_t idle_process_max = 0; @@ -1822,6 +1870,7 @@ bool Main::iteration() { double scaled_step = step * time_scale; Engine::get_singleton()->_frame_step = step; + Engine::get_singleton()->_physics_interpolation_fraction = advance.interpolation_fraction; uint64_t physics_process_ticks = 0; uint64_t idle_process_ticks = 0; @@ -1873,7 +1922,9 @@ bool Main::iteration() { uint64_t idle_begin = OS::get_singleton()->get_ticks_usec(); - OS::get_singleton()->get_main_loop()->idle(step * time_scale); + if (OS::get_singleton()->get_main_loop()->idle(step * time_scale)) { + exit = true; + } message_queue->flush(); VisualServer::get_singleton()->sync(); //sync if still drawing from previous frames. @@ -1938,7 +1989,7 @@ bool Main::iteration() { return exit; if (OS::get_singleton()->is_in_low_processor_usage_mode() || !OS::get_singleton()->can_draw()) - 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) + OS::get_singleton()->delay_usec(OS::get_singleton()->get_low_processor_usage_mode_sleep_usec()); //apply some delay to force idle time else { uint32_t frame_delay = Engine::get_singleton()->get_frame_delay(); if (frame_delay) |