diff options
Diffstat (limited to 'core/project_settings.cpp')
| -rw-r--r-- | core/project_settings.cpp | 248 |
1 files changed, 160 insertions, 88 deletions
diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 146b4870e8..407bb78375 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -30,16 +30,17 @@ #include "project_settings.h" -#include "bind/core_bind.h" -#include "core_string_names.h" -#include "io/file_access_network.h" -#include "io/file_access_pack.h" -#include "io/marshalls.h" -#include "os/dir_access.h" -#include "os/file_access.h" -#include "os/keyboard.h" -#include "os/os.h" -#include "variant_parser.h" +#include "core/bind/core_bind.h" +#include "core/core_string_names.h" +#include "core/io/file_access_network.h" +#include "core/io/file_access_pack.h" +#include "core/io/marshalls.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" +#include "core/variant_parser.h" + #include <zlib.h> #define FORMAT_VERSION 4 @@ -59,7 +60,7 @@ String ProjectSettings::get_resource_path() const { String ProjectSettings::localize_path(const String &p_path) const { if (resource_path == "") - return p_path; //not initialied yet + return p_path; //not initialized yet if (p_path.begins_with("res://") || p_path.begins_with("user://") || (p_path.is_abs_path() && !p_path.begins_with(resource_path))) @@ -191,7 +192,7 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const { name = feature_overrides[name]; } if (!props.has(name)) { - print_line("WARNING: not found: " + String(name)); + WARN_PRINTS("Property not found: " + String(name)); return false; } r_ret = props[name].variant; @@ -287,9 +288,28 @@ void ProjectSettings::_convert_to_last_version() { } } +/* + * This method is responsible for loading a project.godot file and/or data file + * using the following merit order: + * - If using NetworkClient, try to lookup project file or fail. + * - If --main-pack was passed by the user (`p_main_pack`), load it or fail. + * - Search for .pck file matching binary name. There are two possibilities: + * o exec_path.get_basename() + '.pck' (e.g. 'win_game.exe' -> 'win_game.pck') + * o exec_path + '.pck' (e.g. 'linux_game' -> 'linux_game.pck') + * For each tentative, if the file exists, load it or fail. + * - On relevant platforms (Android/iOS), lookup project file in OS resource path. + * If found, load it or fail. + * - Lookup project file in passed `p_path` (--path passed by the user), i.e. we + * are running from source code. + * If not found and `p_upwards` is true (--upwards passed by the user), look for + * project files in parent folders up to the system root (used to run a game + * from command line while in a subfolder). + * If a project file is found, load it or fail. + * If nothing was found, error out. + */ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) { - //If looking for files in network, just use network! + // If looking for files in a network client, use it directly if (FileAccessNetworkClient::get_singleton()) { @@ -301,9 +321,7 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo return err; } - String exec_path = OS::get_singleton()->get_executable_path(); - - //Attempt with a passed main pack first + // Attempt with a user-defined main pack first if (p_main_pack != "") { @@ -319,25 +337,39 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo return err; } - //Attempt with execname.pck + // Attempt with exec_name.pck + // (This is the usual case when distributing a Godot game.) + + // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle) + // or the exec path's basename + '.pck' (Windows). + // We need to test both possibilities as extensions for Linux binaries are optional + // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). + + String exec_path = OS::get_singleton()->get_executable_path(); + if (exec_path != "") { bool found = false; - // get our filename without our path (note, using exec_path.get_file before get_basename anymore because not all file systems have dots in their file names!) - String filebase_name = exec_path.get_file().get_basename(); + String exec_dir = exec_path.get_base_dir(); + String exec_filename = exec_path.get_file(); + String exec_basename = exec_filename.get_basename(); + + // Try to load data pack at the location of the executable + // As mentioned above, we have two potential names to attempt - // try to open at the location of executable - String datapack_name = exec_path.get_base_dir().plus_file(filebase_name) + ".pck"; - if (_load_resource_pack(datapack_name)) { + if (_load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) || + _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck"))) { found = true; } else { - datapack_name = filebase_name + ".pck"; - if (_load_resource_pack(datapack_name)) { + // If we couldn't find them next to the executable, we attempt + // the current working directory. Same story, two tests. + if (_load_resource_pack(exec_basename + ".pck") || + _load_resource_pack(exec_filename + ".pck")) { found = true; } } - // if we opened our package, try and load our project... + // If we opened our package, try and load our project if (found) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK) { @@ -349,17 +381,15 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo } } - //Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this) - if (OS::get_singleton()->get_resource_dir() != "") { - //OS will call Globals->get_resource_path which will be empty if not overridden! - //if the OS would rather use somewhere else, then it will not be empty. + // Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this) + if (OS::get_singleton()->get_resource_dir() != "") { + // OS will call ProjectSettings->get_resource_path which will be empty if not overridden! + // If the OS would rather use a specific location, then it will not be empty. resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/"); - if (resource_path.length() && resource_path[resource_path.length() - 1] == '/') + if (resource_path != "" && resource_path[resource_path.length() - 1] == '/') { resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end - - // data.pck and data.zip are deprecated and no longer supported, apologies. - // make sure this is loaded from the resource path + } Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK) { @@ -370,21 +400,19 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo return err; } - //Nothing was found, try to find a project.godot somewhere! + // Nothing was found, try to find a project file in provided path (`p_path`) + // or, if requested (`p_upwards`) in parent directories. DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); ERR_FAIL_COND_V(!d, ERR_CANT_CREATE); - d->change_dir(p_path); - String candidate = d->get_current_dir(); String current_dir = d->get_current_dir(); - + String candidate = current_dir; bool found = false; Error err; while (true) { - err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary")); if (err == OK) { // Optional, we don't mind if it fails @@ -395,10 +423,10 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo } if (p_upwards) { - // Try to load settings ascending through dirs shape! + // Try to load settings ascending through parent directories d->change_dir(".."); if (d->get_current_dir() == current_dir) - break; //not doing anything useful + break; // not doing anything useful current_dir = d->get_current_dir(); } else { break; @@ -415,6 +443,8 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo if (resource_path.length() && resource_path[resource_path.length() - 1] == '/') resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end + // If we're loading a project.godot from source code, we can operate some + // ProjectSettings conversions if need be. _convert_to_last_version(); return OK; @@ -953,7 +983,8 @@ ProjectSettings::ProjectSettings() { disable_feature_overrides = false; registering_order = true; - Array va; + Array events; + Dictionary action; Ref<InputEventKey> key; Ref<InputEventJoypadButton> joyb; @@ -965,122 +996,162 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("application/config/use_custom_user_dir", false); GLOBAL_DEF("application/config/custom_user_dir_name", ""); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_ENTER); - va.push_back(key); + events.push_back(key); key.instance(); key->set_scancode(KEY_KP_ENTER); - va.push_back(key); + events.push_back(key); key.instance(); key->set_scancode(KEY_SPACE); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_BUTTON_0); - va.push_back(joyb); - GLOBAL_DEF("input/ui_accept", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_accept", action); input_presets.push_back("input/ui_accept"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_SPACE); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_BUTTON_3); - va.push_back(joyb); - GLOBAL_DEF("input/ui_select", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_select", action); input_presets.push_back("input/ui_select"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_ESCAPE); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_BUTTON_1); - va.push_back(joyb); - GLOBAL_DEF("input/ui_cancel", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_cancel", action); input_presets.push_back("input/ui_cancel"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_TAB); - va.push_back(key); - GLOBAL_DEF("input/ui_focus_next", va); + events.push_back(key); + action["events"] = events; + GLOBAL_DEF("input/ui_focus_next", action); input_presets.push_back("input/ui_focus_next"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_TAB); key->set_shift(true); - va.push_back(key); - GLOBAL_DEF("input/ui_focus_prev", va); + events.push_back(key); + action["events"] = events; + GLOBAL_DEF("input/ui_focus_prev", action); input_presets.push_back("input/ui_focus_prev"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_LEFT); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_DPAD_LEFT); - va.push_back(joyb); - GLOBAL_DEF("input/ui_left", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_left", action); input_presets.push_back("input/ui_left"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_RIGHT); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_DPAD_RIGHT); - va.push_back(joyb); - GLOBAL_DEF("input/ui_right", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_right", action); input_presets.push_back("input/ui_right"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_UP); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_DPAD_UP); - va.push_back(joyb); - GLOBAL_DEF("input/ui_up", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_up", action); input_presets.push_back("input/ui_up"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_DOWN); - va.push_back(key); + events.push_back(key); joyb.instance(); joyb->set_button_index(JOY_DPAD_DOWN); - va.push_back(joyb); - GLOBAL_DEF("input/ui_down", va); + events.push_back(joyb); + action["events"] = events; + GLOBAL_DEF("input/ui_down", action); input_presets.push_back("input/ui_down"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_PAGEUP); - va.push_back(key); - GLOBAL_DEF("input/ui_page_up", va); + events.push_back(key); + action["events"] = events; + GLOBAL_DEF("input/ui_page_up", action); input_presets.push_back("input/ui_page_up"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_PAGEDOWN); - va.push_back(key); - GLOBAL_DEF("input/ui_page_down", va); + events.push_back(key); + action["events"] = events; + GLOBAL_DEF("input/ui_page_down", action); input_presets.push_back("input/ui_page_down"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_HOME); - va.push_back(key); - GLOBAL_DEF("input/ui_home", va); + events.push_back(key); + action["events"] = events; + GLOBAL_DEF("input/ui_home", action); input_presets.push_back("input/ui_home"); - va = Array(); + action = Dictionary(); + action["deadzone"] = Variant(0.5f); + events = Array(); key.instance(); key->set_scancode(KEY_END); - va.push_back(key); - GLOBAL_DEF("input/ui_end", va); + events.push_back(key); + action["events"] = events; + GLOBAL_DEF("input/ui_end", action); input_presets.push_back("input/ui_end"); //GLOBAL_DEF("display/window/handheld/orientation", "landscape"); @@ -1091,6 +1162,7 @@ ProjectSettings::ProjectSettings() { custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects"); GLOBAL_DEF("debug/settings/profiler/max_functions", 16384); + custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1"); //assigning here, because using GLOBAL_GET on every block for compressing can be slow Compression::zstd_long_distance_matching = GLOBAL_DEF("compression/formats/zstd/long_distance_matching", false); |