summaryrefslogtreecommitdiff
path: root/main/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/main.cpp')
-rw-r--r--main/main.cpp87
1 files changed, 65 insertions, 22 deletions
diff --git a/main/main.cpp b/main/main.cpp
index bfb0eacdfc..7d803d901d 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -148,7 +148,7 @@ static bool cmdline_tool = false;
static String locale;
static bool show_help = false;
static bool auto_quit = false;
-static OS::ProcessID allow_focus_steal_pid = 0;
+static OS::ProcessID editor_pid = 0;
#ifdef TOOLS_ENABLED
static bool auto_build_solutions = false;
static String debug_server_uri;
@@ -175,6 +175,7 @@ static Vector2 init_custom_pos;
static bool use_debug_profiler = false;
#ifdef DEBUG_ENABLED
static bool debug_collisions = false;
+static bool debug_paths = false;
static bool debug_navigation = false;
#endif
static int frame_delay = 0;
@@ -357,6 +358,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
#if defined(DEBUG_ENABLED)
OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
+ OS::get_singleton()->print(" --debug-paths Show path lines when running the scene.\n");
OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
#endif
@@ -408,6 +410,8 @@ Error Main::test_setup() {
String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2);
+ register_core_settings(); //here globals are present
+
translation_server = memnew(TranslationServer);
tsman = memnew(TextServerManager);
@@ -619,11 +623,18 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
/* argument parsing and main creation */
List<String> args;
List<String> main_args;
+ List<String> platform_args = OS::get_singleton()->get_cmdline_platform_args();
+ // Add command line arguments.
for (int i = 0; i < argc; i++) {
args.push_back(String::utf8(argv[i]));
}
+ // Add arguments received from macOS LaunchService (URL schemas, file associations).
+ for (const String &arg : platform_args) {
+ args.push_back(arg);
+ }
+
List<String>::Element *I = args.front();
while (I) {
@@ -671,9 +682,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
packed_data->add_pack_source(zip_packed_data);
#endif
+ // Default exit code, can be modified for certain errors.
+ Error exit_code = ERR_INVALID_PARAMETER;
+
I = args.front();
while (I) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
// Ignore the process serial number argument passed by macOS Gatekeeper.
// Otherwise, Godot would try to open a non-existent project on the first start and abort.
if (I->get().begins_with("-psn_")) {
@@ -686,10 +700,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help
show_help = true;
+ exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
goto error;
} else if (I->get() == "--version") {
print_line(get_full_version_string());
+ exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
goto error;
} else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output
@@ -1030,10 +1046,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (I->next()) {
String p = I->next()->get();
- if (OS::get_singleton()->set_cwd(p) == OK) {
- //nothing
- } else {
- project_path = I->next()->get(); //use project_path instead
+ if (OS::get_singleton()->set_cwd(p) != OK) {
+ OS::get_singleton()->print("Invalid project path specified: \"%s\", aborting.\n", p.utf8().get_data());
+ goto error;
}
N = I->next()->next();
} else {
@@ -1107,6 +1122,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#if defined(DEBUG_ENABLED)
} else if (I->get() == "--debug-collisions") {
debug_collisions = true;
+ } else if (I->get() == "--debug-paths") {
+ debug_paths = true;
} else if (I->get() == "--debug-navigation") {
debug_navigation = true;
} else if (I->get() == "--debug-stringnames") {
@@ -1125,9 +1142,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->print("Missing remote debug host address, aborting.\n");
goto error;
}
- } else if (I->get() == "--allow_focus_steal_pid") { // not exposed to user
+ } else if (I->get() == "--editor-pid") { // not exposed to user
if (I->next()) {
- allow_focus_steal_pid = I->next()->get().to_int();
+ editor_pid = I->next()->get().to_int();
N = I->next()->next();
} else {
OS::get_singleton()->print("Missing editor PID argument, aborting.\n");
@@ -1257,7 +1274,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
PROPERTY_HINT_RANGE,
"0, 200, 1, or_greater"));
- EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints);
+ EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints, []() {
+ if (editor_pid) {
+ DisplayServer::get_singleton()->enable_for_stealing_focus(editor_pid);
+ }
+ });
#ifdef TOOLS_ENABLED
if (editor) {
@@ -1451,11 +1472,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
/* Determine audio and video drivers */
// Display driver, e.g. X11, Wayland.
- // print_line("requested display driver : " + display_driver);
+ // Make sure that headless is the last one, which it is assumed to be by design.
+ DEV_ASSERT(String("headless") == DisplayServer::get_create_function_name(DisplayServer::get_create_function_count() - 1));
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
String name = DisplayServer::get_create_function_name(i);
- // print_line("\t" + itos(i) + " : " + name);
-
if (display_driver == name) {
display_driver_idx = i;
break;
@@ -1463,6 +1483,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (display_driver_idx < 0) {
+ // If the requested driver wasn't found, pick the first entry.
+ // If all else failed it would be the headless server.
display_driver_idx = 0;
}
@@ -1475,6 +1497,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
audio_driver = GLOBAL_GET("audio/driver/driver");
}
+ // Make sure that dummy is the last one, which it is assumed to be by design.
+ DEV_ASSERT(String("Dummy") == AudioDriverManager::get_driver(AudioDriverManager::get_driver_count() - 1)->get_name());
for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
audio_driver_idx = i;
@@ -1483,7 +1507,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (audio_driver_idx < 0) {
- audio_driver_idx = 0; // 0 Is always available as the dummy driver (no sound)
+ // If the requested driver wasn't found, pick the first entry.
+ // If all else failed it would be the dummy driver (no sound).
+ audio_driver_idx = 0;
}
if (write_movie_path != String()) {
@@ -1632,7 +1658,7 @@ error:
OS::get_singleton()->finalize_core();
locale = String();
- return ERR_INVALID_PARAMETER;
+ return exit_code;
}
Error Main::setup2(Thread::ID p_main_tid_override) {
@@ -1676,10 +1702,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Error err;
display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err != OK || display_server == nullptr) {
- //ok i guess we can't use this display server, try other ones
- for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
+ // We can't use this display server, try other ones as fallback.
+ // Skip headless (always last registered) because that's not what users
+ // would expect if they didn't request it explicitly.
+ for (int i = 0; i < DisplayServer::get_create_function_count() - 1; i++) {
if (i == display_driver_idx) {
- continue; //don't try the same twice
+ continue; // Don't try the same twice.
}
display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err == OK && display_server != nullptr) {
@@ -1815,10 +1843,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true);
}
- if (allow_focus_steal_pid) {
- DisplayServer::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid);
- }
-
MAIN_PRINT("Main: Load Boot Image");
Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3));
@@ -2175,6 +2199,13 @@ bool Main::start() {
#endif
}
+ uint64_t minimum_time_msec = GLOBAL_DEF("application/boot_splash/minimum_display_time", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("application/boot_splash/minimum_display_time",
+ PropertyInfo(Variant::INT,
+ "application/boot_splash/minimum_display_time",
+ PROPERTY_HINT_RANGE,
+ "0,100,1,or_greater,suffix:ms")); // No negative numbers.
+
#ifdef TOOLS_ENABLED
if (!doc_tool_path.is_empty()) {
// Needed to instance editor-only classes for their default values
@@ -2375,6 +2406,9 @@ bool Main::start() {
if (debug_collisions) {
sml->set_debug_collisions_hint(true);
}
+ if (debug_paths) {
+ sml->set_debug_paths_hint(true);
+ }
if (debug_navigation) {
sml->set_debug_navigation_hint(true);
}
@@ -2636,7 +2670,7 @@ bool Main::start() {
ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path);
sml->add_current_scene(scene);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()");
if (!mac_iconpath.is_empty()) {
DisplayServer::get_singleton()->set_native_icon(mac_iconpath);
@@ -2692,6 +2726,15 @@ bool Main::start() {
if (movie_writer) {
movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, write_movie_path);
}
+
+ if (minimum_time_msec) {
+ uint64_t minimum_time = 1000 * minimum_time_msec;
+ uint64_t elapsed_time = OS::get_singleton()->get_ticks_usec();
+ if (elapsed_time < minimum_time) {
+ OS::get_singleton()->delay_usec(minimum_time - elapsed_time);
+ }
+ }
+
return true;
}