diff options
Diffstat (limited to 'main/main.cpp')
-rw-r--r-- | main/main.cpp | 193 |
1 files changed, 149 insertions, 44 deletions
diff --git a/main/main.cpp b/main/main.cpp index 532b5277b5..deffb3a632 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -45,6 +45,7 @@ #include "input_map.h" #include "io/resource_loader.h" #include "scene/main/scene_tree.h" +#include "servers/arvr_server.h" #include "servers/audio_server.h" #include "io/resource_loader.h" @@ -58,6 +59,7 @@ #ifdef TOOLS_ENABLED #include "editor/doc/doc_data.h" +#include "editor/doc/doc_data_class_path.gen.h" #include "editor/editor_node.h" #include "editor/project_manager.h" #endif @@ -73,6 +75,7 @@ #include "performance.h" #include "translation.h" #include "version.h" +#include "version_hash.gen.h" static ProjectSettings *globals = NULL; static Engine *engine = NULL; @@ -80,6 +83,7 @@ static InputMap *input_map = NULL; static bool _start_success = false; static ScriptDebugger *script_debugger = NULL; AudioServer *audio_server = NULL; +ARVRServer *arvr_server = NULL; static MessageQueue *message_queue = NULL; static Performance *performance = NULL; @@ -111,6 +115,8 @@ static int init_screen = -1; static bool use_vsync = true; static bool editor = false; static bool show_help = false; +static bool disable_render_loop = false; +static int fixed_fps = -1; static OS::ProcessID allow_focus_steal_pid = 0; @@ -119,6 +125,14 @@ static String unescape_cmdline(const String &p_str) { return p_str.replace("%20", " "); } +static String get_full_version_string() { + + String hash = String(VERSION_HASH); + if (hash.length() != 0) + hash = "." + hash.left(7); + return String(VERSION_MKSTRING) + hash; +} + //#define DEBUG_INIT #ifdef DEBUG_INIT @@ -129,7 +143,7 @@ static String unescape_cmdline(const String &p_str) { void Main::print_help(const char *p_binary) { - OS::get_singleton()->print(VERSION_FULL_NAME " - https://godotengine.org\n"); + print_line(String(_MKSTR(VERSION_NAME)) + " v" + get_full_version_string() + " - https://godotengine.org"); 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"); @@ -138,6 +152,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print("General options:\n"); OS::get_singleton()->print(" -h, --help Display this help message.\n"); + OS::get_singleton()->print(" --version Display the version string.\n"); OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n"); OS::get_singleton()->print(" --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n"); OS::get_singleton()->print("\n"); @@ -149,6 +164,7 @@ void Main::print_help(const char *p_binary) { #endif 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"); + OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n"); 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"); @@ -175,7 +191,7 @@ void Main::print_help(const char *p_binary) { 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"); - OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS only).\n"); + 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"); @@ -190,6 +206,9 @@ void Main::print_help(const char *p_binary) { #endif 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"); + OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n"); + OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n"); + OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Standalone tools:\n"); @@ -197,7 +216,7 @@ void Main::print_help(const char *p_binary) { #ifdef TOOLS_ENABLED 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"); - OS::get_singleton()->print(" --doctool <file> Dump the whole engine API to <file> in XML format. If <file> exists, it will be merged.\n"); + 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"); OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); #ifdef DEBUG_METHODS_ENABLED OS::get_singleton()->print(" --gdnative-generate-json-api Generate JSON dump of the Godot API for GDNative bindings.\n"); @@ -215,7 +234,6 @@ void Main::print_help(const char *p_binary) { } Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) { - RID_OwnerBase::init_rid(); OS::get_singleton()->initialize_core(); @@ -238,10 +256,15 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph register_core_settings(); //here globals is present + OS::get_singleton()->initialize_logger(); + translation_server = memnew(TranslationServer); performance = memnew(Performance); + ClassDB::register_class<Performance>(); globals->add_singleton(ProjectSettings::Singleton("Performance", performance)); + GLOBAL_DEF("debug/settings/crash_handler/message", String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues")); + MAIN_PRINT("Main: Parse CMDLine"); /* argument parsing and main creation */ @@ -260,7 +283,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph while (I) { I->get() = unescape_cmdline(I->get().strip_escapes()); - //print_line("CMD: "+I->get()); I = I->next(); } @@ -271,6 +293,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph String video_driver = ""; String audio_driver = ""; String game_path = "."; + bool upwards = false; String debug_mode; String debug_host; String main_pack; @@ -310,6 +333,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph show_help = true; goto error; + } else if (I->get() == "--version") { + + print_line(get_full_version_string()); + goto error; + } else if (I->get() == "--resolution") { // force resolution if (I->next()) { @@ -474,6 +502,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing relative or absolute path, aborting.\n"); goto error; } + } else if (I->get() == "-u" || I->get() == "--upwards") { // scan folders upwards + upwards = true; } else if (I->get().ends_with("project.godot")) { String path; String file = I->get(); @@ -567,6 +597,18 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing editor PID argument, aborting.\n"); goto error; } + } 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; + } + } else if (I->get() == "--disable-crash-handler") { + OS::get_singleton()->disable_crash_handler(); } else { //test for game path @@ -659,7 +701,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #endif - if (globals->setup(game_path, main_pack) != OK) { + if (globals->setup(game_path, main_pack, upwards) != OK) { #ifdef TOOLS_ENABLED editor = false; @@ -691,7 +733,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifdef TOOLS_ENABLED - if (main_args.size() == 0 && (!ProjectSettings::get_singleton()->has("application/run/main_loop_type")) && (!ProjectSettings::get_singleton()->has("application/run/main_scene") || String(ProjectSettings::get_singleton()->get("application/run/main_scene")) == "")) + 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")) == "")) use_custom_res = false; //project manager (run without arguments) #endif @@ -704,21 +746,21 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph //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))); - if (!force_res && use_custom_res && globals->has("display/window/size/width")) + if (!force_res && use_custom_res && globals->has_setting("display/window/size/width")) video_mode.width = globals->get("display/window/size/width"); - if (!force_res && use_custom_res && globals->has("display/window/size/height")) + if (!force_res && use_custom_res && globals->has_setting("display/window/size/height")) video_mode.height = globals->get("display/window/size/height"); - if (!editor && ((globals->has("display/window/dpi/allow_hidpi") && !globals->get("display/window/dpi/allow_hidpi")) || force_lowdpi)) { + if (!editor && ((globals->has_setting("display/window/dpi/allow_hidpi") && !globals->get("display/window/dpi/allow_hidpi")) || force_lowdpi)) { OS::get_singleton()->_allow_hidpi = false; } - if (use_custom_res && globals->has("display/window/size/fullscreen")) + if (use_custom_res && globals->has_setting("display/window/size/fullscreen")) video_mode.fullscreen = globals->get("display/window/size/fullscreen"); - if (use_custom_res && globals->has("display/window/size/resizable")) + if (use_custom_res && globals->has_setting("display/window/size/resizable")) video_mode.resizable = globals->get("display/window/size/resizable"); - if (use_custom_res && globals->has("display/window/size/borderless")) + if (use_custom_res && globals->has_setting("display/window/size/borderless")) video_mode.borderless_window = globals->get("display/window/size/borderless"); - if (!force_res && use_custom_res && globals->has("display/window/size/test_width") && globals->has("display/window/size/test_height")) { + if (!force_res && use_custom_res && 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) { @@ -739,6 +781,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2); GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3); + if (editor) { + OS::get_singleton()->_allow_hidpi = true; //editors always in hidpi + } 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); if (rtm == -1) { @@ -896,11 +941,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) { OS::get_singleton()->set_window_position(init_custom_pos); } - //right moment to create and initialize the audio server + // right moment to create and initialize the audio server audio_server = memnew(AudioServer); audio_server->init(); + // also init our arvr_server from here + arvr_server = memnew(ARVRServer); + OS::get_singleton()->set_use_vsync(use_vsync); register_core_singletons(); @@ -970,8 +1018,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) { #endif } +#ifdef TOOLS_ENABLED Ref<Image> icon = memnew(Image(app_icon_png)); OS::get_singleton()->set_icon(icon); +#endif } MAIN_PRINT("Main: DCC"); @@ -1062,6 +1112,7 @@ bool Main::start() { ERR_FAIL_COND_V(!_start_success, false); + bool hasicon = false; bool editor = false; String doc_tool; List<String> removal_docs; @@ -1098,10 +1149,20 @@ bool Main::start() { test = args[i + 1]; } else if (args[i] == "--export") { editor = true; //needs editor - _export_preset = args[i + 1]; + if (i + 1 < args.size()) { + _export_preset = args[i + 1]; + } else { + ERR_PRINT("Export preset name not specified"); + return false; + } } else if (args[i] == "--export-debug") { editor = true; //needs editor - _export_preset = args[i + 1]; + if (i + 1 < args.size()) { + _export_preset = args[i + 1]; + } else { + ERR_PRINT("Export preset name not specified"); + return false; + } export_debug = true; } else { // The parameter does not match anything known, don't skip the next argument @@ -1119,26 +1180,46 @@ bool Main::start() { #ifdef TOOLS_ENABLED if (doc_tool != "") { + { + 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); + } + } DocData doc; doc.generate(doc_base); DocData docsrc; - if (docsrc.load(doc_tool) == OK) { - print_line("Doc exists. Merging.."); - doc.merge_from(docsrc); - } else { - print_line("No Doc exists. Generating empty."); + Map<String, String> doc_data_classes; + Set<String> checked_paths; + print_line("Loading docs.."); + + for (int i = 0; i < _doc_data_class_path_count; i++) { + String path = doc_tool.plus_file(_doc_data_class_paths[i].path); + String name = _doc_data_class_paths[i].name; + doc_data_classes[name] = path; + if (!checked_paths.has(path)) { + checked_paths.insert(path); + docsrc.load_classes(path); + print_line("Loading docs from: " + path); + } } - for (List<String>::Element *E = removal_docs.front(); E; E = E->next()) { - DocData rmdoc; - if (rmdoc.load(E->get()) == OK) { - print_line(String("Removing classes in ") + E->get()); - doc.remove_from(rmdoc); - } + String index_path = doc_tool.plus_file("doc/classes"); + docsrc.load_classes(index_path); + checked_paths.insert(index_path); + print_line("Loading docs from: " + index_path); + + print_line("Merging docs.."); + doc.merge_from(docsrc); + for (Set<String>::Element *E = checked_paths.front(); E; E = E->next()) { + print_line("Erasing old docs at: " + E->get()); + DocData::erase_classes(E->get()); } - doc.save(doc_tool); + print_line("Generating new docs.."); + doc.save_classes(index_path, doc_data_classes); return false; } @@ -1269,7 +1350,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)); - int stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1); + real_t stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1.0f); SceneTree::StretchMode sml_sm = SceneTree::STRETCH_MODE_DISABLED; if (stretch_mode == "2d") @@ -1309,6 +1390,9 @@ bool Main::start() { Viewport::Usage usage = Viewport::Usage(int(GLOBAL_GET("rendering/quality/intended_usage/framebuffer_allocation"))); sml->get_root()->set_usage(usage); + bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); + sml->get_root()->set_snap_controls_to_pixels(snap_controls); + } else { GLOBAL_DEF("display/window/stretch/mode", "disabled"); ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport")); @@ -1318,6 +1402,7 @@ bool Main::start() { ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::STRING, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1,8,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); } String local_game_path; @@ -1359,6 +1444,8 @@ bool Main::start() { if (editor) { Error serr = editor_node->load_scene(local_game_path); + if (serr != OK) + ERR_PRINT("Failed to load scene"); OS::get_singleton()->set_context(OS::CONTEXT_EDITOR); } #endif @@ -1463,8 +1550,10 @@ bool Main::start() { if (iconpath != "") { Ref<Image> icon; icon.instance(); - if (icon->load(iconpath) == OK) + if (icon->load(iconpath) == OK) { OS::get_singleton()->set_icon(icon); + hasicon = true; + } } } } @@ -1481,6 +1570,11 @@ bool Main::start() { #endif } + if (!hasicon) { + Ref<Image> icon = memnew(Image(app_icon_png)); + OS::get_singleton()->set_icon(icon); + } + OS::get_singleton()->set_main_loop(main_loop); return true; @@ -1494,7 +1588,7 @@ uint32_t Main::frame = 0; bool Main::force_redraw_requested = false; //for performance metrics -static uint64_t fixed_process_max = 0; +static uint64_t physics_process_max = 0; static uint64_t idle_process_max = 0; bool Main::iteration() { @@ -1505,6 +1599,9 @@ bool Main::iteration() { uint64_t ticks_elapsed = ticks - last_ticks; double step = (double)ticks_elapsed / 1000000.0; + if (fixed_fps != -1) + step = 1.0 / fixed_fps; + float frame_slice = 1.0 / Engine::get_singleton()->get_iterations_per_second(); Engine::get_singleton()->_frame_step = step; @@ -1514,14 +1611,14 @@ bool Main::iteration() { return false; */ - uint64_t fixed_process_ticks = 0; + uint64_t physics_process_ticks = 0; uint64_t idle_process_ticks = 0; frame += ticks_elapsed; last_ticks = ticks; - if (step > frame_slice * 8) + if (fixed_fps == -1 && step > frame_slice * 8) step = frame_slice * 8; time_accum += step; @@ -1532,11 +1629,11 @@ bool Main::iteration() { int iters = 0; - Engine::get_singleton()->_in_fixed = true; + Engine::get_singleton()->_in_physics = true; while (time_accum > frame_slice) { - uint64_t fixed_begin = OS::get_singleton()->get_ticks_usec(); + uint64_t physics_begin = OS::get_singleton()->get_ticks_usec(); PhysicsServer::get_singleton()->sync(); PhysicsServer::get_singleton()->flush_queries(); @@ -1559,13 +1656,13 @@ bool Main::iteration() { time_accum -= frame_slice; message_queue->flush(); - fixed_process_ticks = MAX(fixed_process_ticks, OS::get_singleton()->get_ticks_usec() - fixed_begin); // keep the largest one for reference - fixed_process_max = MAX(OS::get_singleton()->get_ticks_usec() - fixed_begin, fixed_process_max); + 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); iters++; - Engine::get_singleton()->_fixed_frames++; + Engine::get_singleton()->_physics_frames++; } - Engine::get_singleton()->_in_fixed = false; + Engine::get_singleton()->_in_physics = false; uint64_t idle_begin = OS::get_singleton()->get_ticks_usec(); @@ -1574,7 +1671,7 @@ bool Main::iteration() { VisualServer::get_singleton()->sync(); //sync if still drawing from previous frames. - if (OS::get_singleton()->can_draw()) { + if (OS::get_singleton()->can_draw() && !disable_render_loop) { if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) { if (VisualServer::get_singleton()->has_changed()) { @@ -1601,7 +1698,7 @@ bool Main::iteration() { if (script_debugger) { if (script_debugger->is_profiling()) { - script_debugger->profiling_set_frame_times(USEC_TO_SEC(frame_time), USEC_TO_SEC(idle_process_ticks), USEC_TO_SEC(fixed_process_ticks), frame_slice); + 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); } script_debugger->idle_poll(); } @@ -1617,14 +1714,17 @@ bool Main::iteration() { Engine::get_singleton()->_fps = frames; performance->set_process_time(USEC_TO_SEC(idle_process_max)); - performance->set_fixed_process_time(USEC_TO_SEC(fixed_process_max)); + performance->set_physics_process_time(USEC_TO_SEC(physics_process_max)); idle_process_max = 0; - fixed_process_max = 0; + physics_process_max = 0; frame %= 1000000; frames = 0; } + if (fixed_fps != -1) + return exit; + if (OS::get_singleton()->is_in_low_processor_usage_mode() || !OS::get_singleton()->can_draw()) OS::get_singleton()->delay_usec(16600); //apply some delay to force idle time (results in about 60 FPS max) else { @@ -1680,6 +1780,11 @@ void Main::cleanup() { memdelete(audio_server); } + if (arvr_server) { + // cleanup now before we pull the rug from underneath... + memdelete(arvr_server); + } + unregister_driver_types(); unregister_module_types(); unregister_scene_types(); |