diff --git a/core/os/os.cpp b/core/os/os.cpp index 790e9043d52..1d6561a7dff 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -408,6 +408,10 @@ Error OS::set_cwd(const String &p_cwd) { return ERR_CANT_OPEN; } +String OS::get_cwd() const { + return "."; +} + Dictionary OS::get_memory_info() const { Dictionary meminfo; diff --git a/core/os/os.h b/core/os/os.h index 346584547a8..5275a30c928 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -205,6 +205,7 @@ public: virtual Error shell_open(const String &p_uri); virtual Error shell_show_in_file_manager(String p_path, bool p_open_folder = true); virtual Error set_cwd(const String &p_cwd); + virtual String get_cwd() const; virtual bool has_environment(const String &p_var) const = 0; virtual String get_environment(const String &p_var) const = 0; diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 8c64ba10ad3..b6f39144812 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -1096,6 +1096,16 @@ Error OS_Unix::set_cwd(const String &p_cwd) { return OK; } +String OS_Unix::get_cwd() const { + String dir; + char real_current_dir_name[2048]; + ERR_FAIL_NULL_V(getcwd(real_current_dir_name, 2048), "."); + if (dir.append_utf8(real_current_dir_name) != OK) { + dir = real_current_dir_name; + } + return dir; +} + bool OS_Unix::has_environment(const String &p_var) const { return getenv(p_var.utf8().get_data()) != nullptr; } diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 977ac50b0d7..456689584a3 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -101,6 +101,7 @@ public: virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String &p_name, void *&p_symbol_handle, bool p_optional = false) override; virtual Error set_cwd(const String &p_cwd) override; + virtual String get_cwd() const override; virtual String get_name() const override; virtual String get_distribution_name() const override; diff --git a/main/main.cpp b/main/main.cpp index 5727a27262f..50b9450ead7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -992,6 +992,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->initialize(); #if !defined(OVERRIDE_PATH_ENABLED) && !defined(TOOLS_ENABLED) + String old_cwd = OS::get_singleton()->get_cwd(); #ifdef MACOS_ENABLED String new_cwd = OS::get_singleton()->get_bundle_resource_dir(); if (new_cwd.is_empty() || !new_cwd.is_absolute_path()) { @@ -2019,8 +2020,23 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifdef TOOLS_ENABLED editor = false; #else - const String error_msg = "Error: Couldn't load project data at path \"" + project_path + "\". Is the .pck file missing?\nIf you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n"; - OS::get_singleton()->print("%s", error_msg.utf8().get_data()); + String error_msg = "Error: Couldn't load project data at path \"" + (project_path == "." ? OS::get_singleton()->get_cwd() : project_path) + "\". Is the .pck file missing?\n\n"; +#if !defined(OVERRIDE_PATH_ENABLED) && !defined(TOOLS_ENABLED) + String exec_path = OS::get_singleton()->get_executable_path(); + String exec_basename = exec_path.get_file().get_basename(); + + if (FileAccess::exists(old_cwd.path_join(exec_basename + ".pck"))) { + error_msg += "\"" + exec_basename + ".pck\" was found in the current working directory. To be able to load a project from the CWD, use the `disable_path_overrides=no` SCons option when compiling Godot.\n"; + } else if (FileAccess::exists(old_cwd.path_join("project.godot"))) { + error_msg += "\"project.godot\" was found in the current working directory. To be able to load a project from the CWD, use the `disable_path_overrides=no` SCons option when compiling Godot.\n"; + } else { + error_msg += "If you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n"; + } +#else + error_msg += "If you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n"; +#endif + ERR_PRINT(error_msg); + OS::get_singleton()->alert(error_msg); goto error; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index a24488014c4..1c75523df38 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1678,6 +1678,14 @@ Error OS_Windows::set_cwd(const String &p_cwd) { return OK; } +String OS_Windows::get_cwd() const { + Char16String real_current_dir_name; + size_t str_len = GetCurrentDirectoryW(0, nullptr); + real_current_dir_name.resize_uninitialized(str_len + 1); + GetCurrentDirectoryW(real_current_dir_name.size(), (LPWSTR)real_current_dir_name.ptrw()); + return String::utf16((const char16_t *)real_current_dir_name.get_data()).trim_prefix(R"(\\?\)").replace_char('\\', '/'); +} + Vector OS_Windows::get_system_fonts() const { if (!dwrite_init) { return Vector(); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 4742e7fb01a..a2cadc65c45 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -201,6 +201,7 @@ public: virtual double get_unix_time() const override; virtual Error set_cwd(const String &p_cwd) override; + virtual String get_cwd() const override; virtual void add_frame_delay(bool p_can_draw, bool p_wake_for_events) override; virtual void delay_usec(uint32_t p_usec) const override;