Bläddra i källkod

-Renamed GlobalConfig to ProjectSettings, makes more sense.
-Added system for feature overrides, it's pretty cool :)

Juan Linietsky 8 år sedan
förälder
incheckning
25678b1876
100 ändrade filer med 1051 tillägg och 694 borttagningar
  1. 3 3
      core/SCsub
  2. 2 2
      core/bind/core_bind.cpp
  3. 1 0
      core/core_string_names.cpp
  4. 1 0
      core/core_string_names.h
  5. 3 3
      core/input_map.cpp
  6. 1 1
      core/io/compression.cpp
  7. 3 3
      core/io/file_access_memory.cpp
  8. 1 1
      core/io/file_access_network.cpp
  9. 1 1
      core/io/packet_peer.cpp
  10. 8 8
      core/io/resource_format_binary.cpp
  11. 5 2
      core/io/resource_import.cpp
  12. 7 7
      core/io/resource_loader.cpp
  13. 2 2
      core/io/resource_saver.cpp
  14. 1 1
      core/message_queue.cpp
  15. 4 4
      core/os/dir_access.cpp
  16. 3 3
      core/os/file_access.cpp
  17. 2 2
      core/os/input.cpp
  18. 1 1
      core/os/input_event.cpp
  19. 21 3
      core/os/os.cpp
  20. 2 1
      core/os/os.h
  21. 163 95
      core/project_settings.cpp
  22. 16 14
      core/project_settings.h
  23. 13 13
      core/register_core_types.cpp
  24. 4 4
      core/script_debugger_remote.cpp
  25. 4 4
      core/translation.cpp
  26. 2 2
      doc/base/classes.xml
  27. 1 1
      drivers/alsa/audio_driver_alsa.cpp
  28. 4 4
      drivers/gles2/rasterizer_gles2.cpp
  29. 1 1
      drivers/gles3/rasterizer_canvas_gles3.cpp
  30. 1 1
      drivers/gles3/rasterizer_gles3.cpp
  31. 8 10
      drivers/gles3/rasterizer_scene_gles3.cpp
  32. 4 4
      drivers/gles3/rasterizer_storage_gles3.cpp
  33. 1 1
      drivers/png/resource_saver_png.cpp
  34. 1 1
      drivers/pulseaudio/audio_driver_pulseaudio.cpp
  35. 1 1
      drivers/rtaudio/audio_driver_rtaudio.cpp
  36. 3 8
      drivers/unix/os_unix.cpp
  37. 0 2
      drivers/unix/os_unix.h
  38. 1 1
      drivers/xaudio2/audio_driver_xaudio2.cpp
  39. 2 2
      editor/asset_library_editor_plugin.cpp
  40. 4 4
      editor/collada/collada.cpp
  41. 1 1
      editor/collada/collada.h
  42. 5 5
      editor/doc/doc_data.cpp
  43. 38 38
      editor/editor_autoload_settings.cpp
  44. 1 1
      editor/editor_data.cpp
  45. 68 15
      editor/editor_export.cpp
  46. 17 1
      editor/editor_export.h
  47. 5 5
      editor/editor_file_system.cpp
  48. 25 25
      editor/editor_node.cpp
  49. 2 2
      editor/editor_node.h
  50. 2 2
      editor/editor_plugin_settings.cpp
  51. 2 2
      editor/editor_resource_preview.cpp
  52. 6 6
      editor/editor_run.cpp
  53. 2 2
      editor/editor_settings.cpp
  54. 3 3
      editor/file_type_cache.cpp
  55. 3 3
      editor/filesystem_dock.cpp
  56. 9 9
      editor/import/resource_importer_texture.cpp
  57. 2 2
      editor/io_plugins/editor_export_scene.cpp
  58. 6 6
      editor/io_plugins/editor_scene_import_plugin.cpp
  59. 2 2
      editor/io_plugins/editor_texture_import_plugin.cpp
  60. 2 2
      editor/plugins/animation_player_editor_plugin.cpp
  61. 2 2
      editor/plugins/animation_tree_editor_plugin.cpp
  62. 4 4
      editor/plugins/canvas_item_editor_plugin.cpp
  63. 1 1
      editor/plugins/editor_preview_plugins.cpp
  64. 1 1
      editor/plugins/resource_preloader_editor_plugin.cpp
  65. 1 1
      editor/plugins/sample_editor_plugin.cpp
  66. 1 1
      editor/plugins/sample_library_editor_plugin.cpp
  67. 3 3
      editor/plugins/script_editor_plugin.cpp
  68. 9 9
      editor/plugins/spatial_editor_plugin.cpp
  69. 1 1
      editor/plugins/sprite_frames_editor_plugin.cpp
  70. 1 1
      editor/plugins/texture_editor_plugin.cpp
  71. 74 3
      editor/project_export.cpp
  72. 9 0
      editor/project_export.h
  73. 259 191
      editor/project_settings_editor.cpp
  74. 9 7
      editor/project_settings_editor.h
  75. 37 7
      editor/property_editor.cpp
  76. 2 0
      editor/property_editor.h
  77. 2 2
      editor/resources_dock.cpp
  78. 2 2
      editor/scene_tree_dock.cpp
  79. 4 4
      editor/script_create_dialog.cpp
  80. 1 1
      editor/script_editor_debugger.cpp
  81. 1 1
      editor/settings_config_dialog.cpp
  82. 31 26
      main/main.cpp
  83. 5 5
      main/tests/test_io.cpp
  84. 2 2
      modules/gdnative/api_generator.cpp
  85. 3 3
      modules/gdnative/gdnative.cpp
  86. 2 2
      modules/gdnative/godot.cpp
  87. 10 10
      modules/gdscript/gd_editor.cpp
  88. 4 4
      modules/gdscript/gd_script.cpp
  89. 2 2
      modules/openssl/stream_peer_openssl.cpp
  90. 1 1
      modules/openssl/stream_peer_openssl.h
  91. 2 2
      modules/theora/video_stream_theora.cpp
  92. 1 1
      modules/visual_script/visual_script.cpp
  93. 5 5
      modules/visual_script/visual_script_flow_control.cpp
  94. 8 8
      modules/visual_script/visual_script_func_nodes.cpp
  95. 7 7
      modules/visual_script/visual_script_nodes.cpp
  96. 2 2
      modules/webm/video_stream_webm.cpp
  97. 1 1
      platform/android/audio_driver_jandroid.cpp
  98. 28 12
      platform/android/export/export.cpp
  99. 2 2
      platform/android/globals/global_defaults.cpp
  100. 4 4
      platform/android/godot_android.cpp

+ 3 - 3
core/SCsub

@@ -14,9 +14,9 @@ for x in env.global_defaults:
     gd_inc += '#include "platform/' + x + '/globals/global_defaults.h"\n'
     gd_call += "\tregister_" + x + "_global_defaults();\n"
 
-gd_cpp = '#include "global_config.h"\n'
+gd_cpp = '#include "project_settings.h"\n'
 gd_cpp += gd_inc
-gd_cpp += "void GlobalConfig::register_global_defaults() {\n" + gd_call + "\n}\n"
+gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n"
 
 f = open("global_defaults.gen.cpp", "wb")
 f.write(gd_cpp)
@@ -48,7 +48,7 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
         print("Invalid AES256 encryption key, not 64 bits hex: " + e)
 
 f = open("script_encryption_key.gen.cpp", "wb")
-f.write("#include \"global_config.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
+f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
 f.close()
 
 

+ 2 - 2
core/bind/core_bind.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "core_bind.h"
 
-#include "core/global_config.h"
+#include "core/project_settings.h"
 #include "geometry.h"
 #include "io/file_access_compressed.h"
 #include "io/file_access_encrypted.h"
@@ -106,7 +106,7 @@ PoolStringArray _ResourceLoader::get_dependencies(const String &p_path) {
 
 bool _ResourceLoader::has(const String &p_path) {
 
-	String local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+	String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 	return ResourceCache::has(local_path);
 };
 

+ 1 - 0
core/core_string_names.cpp

@@ -44,6 +44,7 @@ CoreStringNames::CoreStringNames() {
 	_iter_next = StaticCString::create("_iter_next");
 	_iter_get = StaticCString::create("_iter_get");
 	get_rid = StaticCString::create("get_rid");
+	_custom_features = StaticCString::create("_custom_features");
 #ifdef TOOLS_ENABLED
 	_sections_unfolded = StaticCString::create("_sections_unfolded");
 #endif

+ 1 - 0
core/core_string_names.h

@@ -61,6 +61,7 @@ public:
 	StringName _iter_next;
 	StringName _iter_get;
 	StringName get_rid;
+	StringName _custom_features;
 #ifdef TOOLS_ENABLED
 	StringName _sections_unfolded;
 #endif

+ 3 - 3
core/input_map.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "input_map.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/keyboard.h"
 
 InputMap *InputMap::singleton = NULL;
@@ -189,7 +189,7 @@ void InputMap::load_from_globals() {
 	input_map.clear();
 
 	List<PropertyInfo> pinfo;
-	GlobalConfig::get_singleton()->get_property_list(&pinfo);
+	ProjectSettings::get_singleton()->get_property_list(&pinfo);
 
 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 		const PropertyInfo &pi = E->get();
@@ -201,7 +201,7 @@ void InputMap::load_from_globals() {
 
 		add_action(name);
 
-		Array va = GlobalConfig::get_singleton()->get(pi.name);
+		Array va = ProjectSettings::get_singleton()->get(pi.name);
 
 		for (int i = 0; i < va.size(); i++) {
 

+ 1 - 1
core/io/compression.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "compression.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/copymem.h"
 #include "zip_io.h"
 

+ 3 - 3
core/io/file_access_memory.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "file_access_memory.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "map.h"
 #include "os/copymem.h"
 #include "os/dir_access.h"
@@ -43,8 +43,8 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
 	}
 
 	String name;
-	if (GlobalConfig::get_singleton())
-		name = GlobalConfig::get_singleton()->globalize_path(p_name);
+	if (ProjectSettings::get_singleton())
+		name = ProjectSettings::get_singleton()->globalize_path(p_name);
 	else
 		name = p_name;
 	//name = DirAccess::normalize_path(name);

+ 1 - 1
core/io/file_access_network.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "file_access_network.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/ip.h"
 #include "marshalls.h"
 #include "os/os.h"

+ 1 - 1
core/io/packet_peer.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "packet_peer.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/marshalls.h"
 /* helpers / binders */
 

+ 8 - 8
core/io/resource_format_binary.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "resource_format_binary.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "image.h"
 #include "io/file_access_compressed.h"
 #include "io/marshalls.h"
@@ -317,7 +317,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
 
 					if (path.find("://") == -1 && path.is_rel_path()) {
 						// path is relative to file being loaded, so convert to a resource path
-						path = GlobalConfig::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
+						path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
 					}
 
 					if (remaps.find(path)) {
@@ -346,7 +346,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
 
 						if (path.find("://") == -1 && path.is_rel_path()) {
 							// path is relative to file being loaded, so convert to a resource path
-							path = GlobalConfig::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
+							path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
 						}
 
 						RES res = ResourceLoader::load(path, type);
@@ -1017,7 +1017,7 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(cons
 	}
 
 	Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
-	ria->local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+	ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 	ria->res_path = ria->local_path;
 	//ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
 	ria->open(f);
@@ -1065,7 +1065,7 @@ void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<Str
 	ERR_FAIL_COND(!f);
 
 	Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
-	ria->local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+	ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 	ria->res_path = ria->local_path;
 	//ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
 	ria->get_dependencies(f, p_dependencies, p_add_types);
@@ -1152,7 +1152,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
 		}
 
 		Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
-		ria->local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+		ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 		ria->res_path = ria->local_path;
 		ria->remaps = p_map;
 		//ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
@@ -1281,7 +1281,7 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const
 	}
 
 	Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
-	ria->local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+	ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 	ria->res_path = ria->local_path;
 	//ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
 	String r = ria->recognize(f);
@@ -1984,7 +1984,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
 
 Error ResourceFormatSaverBinary::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
 
-	String local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+	String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 	ResourceFormatSaverBinaryInstance saver;
 	return saver.save(local_path, p_resource, p_flags);
 }

+ 5 - 2
core/io/resource_import.cpp

@@ -49,6 +49,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
 
 	int lines = 0;
 	String error_text;
+	bool path_found = false; //first match must have priority
 	while (true) {
 
 		assign = Variant();
@@ -66,14 +67,16 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
 		}
 
 		if (assign != String()) {
-			if (assign.begins_with("path.") && r_path_and_type.path == String()) {
+			if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) {
 				String feature = assign.get_slicec('.', 1);
 				if (OS::get_singleton()->check_feature_support(feature)) {
 					r_path_and_type.path = value;
+					path_found = true; //first match must have priority
 				}
 
-			} else if (assign == "path") {
+			} else if (!path_found && assign == "path") {
 				r_path_and_type.path = value;
+				path_found = true; //first match must have priority
 			} else if (assign == "type") {
 				r_path_and_type.type = value;
 			}

+ 7 - 7
core/io/resource_loader.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "resource_loader.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_import.h"
 #include "os/file_access.h"
 #include "os/os.h"
@@ -166,7 +166,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
 	if (p_path.is_rel_path())
 		local_path = "res://" + p_path;
 	else
-		local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+		local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 
 	bool xl_remapped = false;
 	String path = _path_remap(local_path, &xl_remapped);
@@ -233,7 +233,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
 	if (p_path.is_rel_path())
 		local_path = "res://" + p_path;
 	else
-		local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+		local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 
 	bool xl_remapped = false;
 	String path = _path_remap(local_path, &xl_remapped);
@@ -304,7 +304,7 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe
 	if (path.is_rel_path())
 		local_path = "res://" + path;
 	else
-		local_path = GlobalConfig::get_singleton()->localize_path(path);
+		local_path = ProjectSettings::get_singleton()->localize_path(path);
 
 	for (int i = 0; i < loader_count; i++) {
 
@@ -327,7 +327,7 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String
 	if (path.is_rel_path())
 		local_path = "res://" + path;
 	else
-		local_path = GlobalConfig::get_singleton()->localize_path(path);
+		local_path = ProjectSettings::get_singleton()->localize_path(path);
 
 	for (int i = 0; i < loader_count; i++) {
 
@@ -350,7 +350,7 @@ String ResourceLoader::get_resource_type(const String &p_path) {
 	if (p_path.is_rel_path())
 		local_path = "res://" + p_path;
 	else
-		local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+		local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 
 	for (int i = 0; i < loader_count; i++) {
 
@@ -430,7 +430,7 @@ void ResourceLoader::reload_translation_remaps() {
 
 void ResourceLoader::load_translation_remaps() {
 
-	Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+	Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 	List<Variant> keys;
 	remaps.get_key_list(&keys);
 	for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {

+ 2 - 2
core/io/resource_saver.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "resource_saver.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/file_access.h"
 #include "resource_loader.h"
 #include "script_language.h"
@@ -64,7 +64,7 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
 
 		String old_path = p_resource->get_path();
 
-		String local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+		String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 
 		RES rwcopy = p_resource;
 		if (p_flags & FLAG_CHANGE_PATH)

+ 1 - 1
core/message_queue.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "message_queue.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "script_language.h"
 
 MessageQueue *MessageQueue::singleton = NULL;

+ 4 - 4
core/os/dir_access.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "dir_access.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/file_access.h"
 #include "os/memory.h"
 #include "os/os.h"
@@ -37,7 +37,7 @@ String DirAccess::_get_root_path() const {
 
 	switch (_access_type) {
 
-		case ACCESS_RESOURCES: return GlobalConfig::get_singleton()->get_resource_path();
+		case ACCESS_RESOURCES: return ProjectSettings::get_singleton()->get_resource_path();
 		case ACCESS_USERDATA: return OS::get_singleton()->get_data_dir();
 		default: return "";
 	}
@@ -200,10 +200,10 @@ String DirAccess::fix_path(String p_path) const {
 
 		case ACCESS_RESOURCES: {
 
-			if (GlobalConfig::get_singleton()) {
+			if (ProjectSettings::get_singleton()) {
 				if (p_path.begins_with("res://")) {
 
-					String resource_path = GlobalConfig::get_singleton()->get_resource_path();
+					String resource_path = ProjectSettings::get_singleton()->get_resource_path();
 					if (resource_path != "") {
 
 						return p_path.replace_first("res:/", resource_path);

+ 3 - 3
core/os/file_access.cpp

@@ -31,7 +31,7 @@
 
 #include "core/io/file_access_pack.h"
 #include "core/io/marshalls.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 
 #include "thirdparty/misc/md5.h"
@@ -135,10 +135,10 @@ String FileAccess::fix_path(const String &p_path) const {
 
 		case ACCESS_RESOURCES: {
 
-			if (GlobalConfig::get_singleton()) {
+			if (ProjectSettings::get_singleton()) {
 				if (r_path.begins_with("res://")) {
 
-					String resource_path = GlobalConfig::get_singleton()->get_resource_path();
+					String resource_path = ProjectSettings::get_singleton()->get_resource_path();
 					if (resource_path != "") {
 
 						return r_path.replace("res:/", resource_path);

+ 2 - 2
core/os/input.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "input.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "input_map.h"
 #include "os/os.h"
 Input *Input::singleton = NULL;
@@ -101,7 +101,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
 	if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released")) {
 
 		List<PropertyInfo> pinfo;
-		GlobalConfig::get_singleton()->get_property_list(&pinfo);
+		ProjectSettings::get_singleton()->get_property_list(&pinfo);
 
 		for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 			const PropertyInfo &pi = E->get();

+ 1 - 1
core/os/input_event.cpp

@@ -103,7 +103,7 @@ bool InputEvent::is_action_type() const {
 if (String(p_method) == "is_action" && p_argidx == 0) {
 
 	List<PropertyInfo> pinfo;
-	GlobalConfig::get_singleton()->get_property_list(&pinfo);
+	ProjectSettings::get_singleton()->get_property_list(&pinfo);
 
 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 		const PropertyInfo &pi = E->get();

+ 21 - 3
core/os/os.cpp

@@ -30,9 +30,9 @@
 #include "os.h"
 
 #include "dir_access.h"
-#include "global_config.h"
 #include "input.h"
 #include "os/file_access.h"
+#include "project_settings.h"
 
 #include <stdarg.h>
 
@@ -260,7 +260,7 @@ String OS::get_locale() const {
 
 String OS::get_resource_dir() const {
 
-	return GlobalConfig::get_singleton()->get_resource_path();
+	return ProjectSettings::get_singleton()->get_resource_path();
 }
 
 String OS::get_system_dir(SystemDir p_dir) const {
@@ -269,7 +269,7 @@ String OS::get_system_dir(SystemDir p_dir) const {
 }
 
 String OS::get_safe_application_name() const {
-	String an = GlobalConfig::get_singleton()->get("application/config/name");
+	String an = ProjectSettings::get_singleton()->get("application/config/name");
 	Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" ");
 	for (int i = 0; i < invalid_char.size(); i++) {
 		an = an.replace(invalid_char[i], "-");
@@ -494,6 +494,24 @@ int OS::get_power_percent_left() {
 	return -1;
 }
 
+bool OS::check_feature_support(const String &p_feature) {
+
+	if (p_feature == get_name())
+		return true;
+#ifdef DEBUG_ENABLED
+	if (p_feature == "debug")
+		return true;
+#else
+	if (p_feature == "release")
+		return true;
+#endif
+
+	if (_check_internal_feature_support(p_feature))
+		return true;
+
+	return false;
+}
+
 OS::OS() {
 	last_error = NULL;
 	singleton = this;

+ 2 - 1
core/os/os.h

@@ -109,6 +109,7 @@ protected:
 	virtual void set_cmdline(const char *p_execpath, const List<String> &p_args);
 
 	void _ensure_data_dir();
+	virtual bool _check_internal_feature_support(const String &p_feature) = 0;
 
 public:
 	typedef int64_t ProcessID;
@@ -408,7 +409,7 @@ public:
 	virtual int get_power_seconds_left();
 	virtual int get_power_percent_left();
 
-	virtual bool check_feature_support(const String &p_feature) = 0;
+	bool check_feature_support(const String &p_feature);
 
 	bool is_hidpi_allowed() const { return _allow_hidpi; }
 	OS();

+ 163 - 95
core/global_config.cpp → core/project_settings.cpp

@@ -27,9 +27,10 @@
 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
-#include "global_config.h"
+#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"
@@ -38,24 +39,23 @@
 #include "os/keyboard.h"
 #include "os/os.h"
 #include "variant_parser.h"
-
 #include <zlib.h>
 
 #define FORMAT_VERSION 3
 
-GlobalConfig *GlobalConfig::singleton = NULL;
+ProjectSettings *ProjectSettings::singleton = NULL;
 
-GlobalConfig *GlobalConfig::get_singleton() {
+ProjectSettings *ProjectSettings::get_singleton() {
 
 	return singleton;
 }
 
-String GlobalConfig::get_resource_path() const {
+String ProjectSettings::get_resource_path() const {
 
 	return resource_path;
 };
 
-String GlobalConfig::localize_path(const String &p_path) const {
+String ProjectSettings::localize_path(const String &p_path) const {
 
 	if (resource_path == "")
 		return p_path; //not initialied yet
@@ -99,13 +99,13 @@ String GlobalConfig::localize_path(const String &p_path) const {
 	};
 }
 
-void GlobalConfig::set_initial_value(const String &p_name, const Variant &p_value) {
+void ProjectSettings::set_initial_value(const String &p_name, const Variant &p_value) {
 
 	ERR_FAIL_COND(!props.has(p_name));
 	props[p_name].initial = p_value;
 }
 
-String GlobalConfig::globalize_path(const String &p_path) const {
+String ProjectSettings::globalize_path(const String &p_path) const {
 
 	if (p_path.begins_with("res://")) {
 
@@ -119,13 +119,44 @@ String GlobalConfig::globalize_path(const String &p_path) const {
 	return p_path;
 }
 
-bool GlobalConfig::_set(const StringName &p_name, const Variant &p_value) {
+bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
 
 	_THREAD_SAFE_METHOD_
 
 	if (p_value.get_type() == Variant::NIL)
 		props.erase(p_name);
 	else {
+
+		if (p_name == CoreStringNames::get_singleton()->_custom_features) {
+			Vector<String> custom_feature_array = p_value;
+			for (int i = 0; i < custom_feature_array.size(); i++) {
+
+				custom_features.insert(custom_feature_array[i]);
+			}
+			return true;
+		}
+
+		if (!disable_feature_overrides) {
+			int dot = p_name.operator String().find(".");
+			if (dot != -1) {
+				Vector<String> s = p_name.operator String().split(".");
+
+				bool override_valid = false;
+				for (int i = 1; i < s.size(); i++) {
+					String feature = s[i].strip_edges();
+					if (OS::get_singleton()->check_feature_support(feature) || custom_features.has(feature)) {
+						override_valid = true;
+						break;
+					}
+				}
+
+				if (override_valid) {
+
+					feature_overrides[s[0]] = p_name;
+				}
+			}
+		}
+
 		if (props.has(p_name)) {
 			if (!props[p_name].overrided)
 				props[p_name].variant = p_value;
@@ -137,15 +168,19 @@ bool GlobalConfig::_set(const StringName &p_name, const Variant &p_value) {
 
 	return true;
 }
-bool GlobalConfig::_get(const StringName &p_name, Variant &r_ret) const {
+bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const {
 
 	_THREAD_SAFE_METHOD_
 
-	if (!props.has(p_name)) {
-		print_line("WARNING: not found: " + String(p_name));
+	StringName name = p_name;
+	if (!disable_feature_overrides && feature_overrides.has(name)) {
+		name = feature_overrides[name];
+	}
+	if (!props.has(name)) {
+		print_line("WARNING: not found: " + String(name));
 		return false;
 	}
-	r_ret = props[p_name].variant;
+	r_ret = props[name].variant;
 	return true;
 }
 
@@ -159,7 +194,7 @@ struct _VCSort {
 	bool operator<(const _VCSort &p_vcs) const { return order == p_vcs.order ? name < p_vcs.name : order < p_vcs.order; }
 };
 
-void GlobalConfig::_get_property_list(List<PropertyInfo> *p_list) const {
+void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
 
 	_THREAD_SAFE_METHOD_
 
@@ -186,8 +221,13 @@ void GlobalConfig::_get_property_list(List<PropertyInfo> *p_list) const {
 
 	for (Set<_VCSort>::Element *E = vclist.front(); E; E = E->next()) {
 
-		if (custom_prop_info.has(E->get().name)) {
-			PropertyInfo pi = custom_prop_info[E->get().name];
+		String prop_info_name = E->get().name;
+		int dot = prop_info_name.find(".");
+		if (dot != -1)
+			prop_info_name = prop_info_name.substr(0, dot);
+
+		if (custom_prop_info.has(prop_info_name)) {
+			PropertyInfo pi = custom_prop_info[prop_info_name];
 			pi.name = E->get().name;
 			pi.usage = E->get().flags;
 			p_list->push_back(pi);
@@ -196,7 +236,7 @@ void GlobalConfig::_get_property_list(List<PropertyInfo> *p_list) const {
 	}
 }
 
-bool GlobalConfig::_load_resource_pack(const String &p_pack) {
+bool ProjectSettings::_load_resource_pack(const String &p_pack) {
 
 	if (PackedData::get_singleton()->is_disabled())
 		return false;
@@ -213,13 +253,13 @@ bool GlobalConfig::_load_resource_pack(const String &p_pack) {
 	return true;
 }
 
-Error GlobalConfig::setup(const String &p_path, const String &p_main_pack) {
+Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
 
 	//If looking for files in network, just use network!
 
 	if (FileAccessNetworkClient::get_singleton()) {
 
-		if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://godot.cfb") == OK) {
+		if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
 
 			_load_settings("res://override.cfg");
 		}
@@ -236,7 +276,7 @@ Error GlobalConfig::setup(const String &p_path, const String &p_main_pack) {
 		bool ok = _load_resource_pack(p_main_pack);
 		ERR_FAIL_COND_V(!ok, ERR_CANT_OPEN);
 
-		if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://godot.cfb") == OK) {
+		if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
 			//load override from location of the main pack
 			_load_settings(p_main_pack.get_base_dir().plus_file("override.cfg"));
 		}
@@ -249,7 +289,7 @@ Error GlobalConfig::setup(const String &p_path, const String &p_main_pack) {
 
 		if (_load_resource_pack(exec_path.get_basename() + ".pck")) {
 
-			if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://godot.cfb") == OK) {
+			if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
 				//load override from location of executable
 				_load_settings(exec_path.get_base_dir().plus_file("override.cfg"));
 			}
@@ -270,7 +310,7 @@ Error GlobalConfig::setup(const String &p_path, const String &p_main_pack) {
 		// data.pck and data.zip are deprecated and no longer supported, apologies.
 		// make sure this is loaded from the resource path
 
-		if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://godot.cfb") == OK) {
+		if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
 			_load_settings("res://override.cfg");
 		}
 
@@ -291,7 +331,7 @@ Error GlobalConfig::setup(const String &p_path, const String &p_main_pack) {
 	while (true) {
 		//try to load settings in ascending through dirs shape!
 
-		if (_load_settings(current_dir + "/project.godot") == OK || _load_settings_binary(current_dir + "/godot.cfb") == OK) {
+		if (_load_settings(current_dir + "/project.godot") == OK || _load_settings_binary(current_dir + "/project.binary") == OK) {
 
 			_load_settings(current_dir + "/override.cfg");
 			candidate = current_dir;
@@ -318,19 +358,19 @@ Error GlobalConfig::setup(const String &p_path, const String &p_main_pack) {
 	return OK;
 }
 
-bool GlobalConfig::has(String p_var) const {
+bool ProjectSettings::has(String p_var) const {
 
 	_THREAD_SAFE_METHOD_
 
 	return props.has(p_var);
 }
 
-void GlobalConfig::set_registering_order(bool p_enable) {
+void ProjectSettings::set_registering_order(bool p_enable) {
 
 	registering_order = p_enable;
 }
 
-Error GlobalConfig::_load_settings_binary(const String p_path) {
+Error ProjectSettings::_load_settings_binary(const String p_path) {
 
 	Error err;
 	FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -343,7 +383,7 @@ Error GlobalConfig::_load_settings_binary(const String p_path) {
 	if (hdr[0] != 'E' || hdr[1] != 'C' || hdr[2] != 'F' || hdr[3] != 'G') {
 
 		memdelete(f);
-		ERR_EXPLAIN("Corrupted header in binary godot.cfb (not ECFG)");
+		ERR_EXPLAIN("Corrupted header in binary project.binary (not ECFG)");
 		ERR_FAIL_V(ERR_FILE_CORRUPT;)
 	}
 
@@ -372,7 +412,7 @@ Error GlobalConfig::_load_settings_binary(const String p_path) {
 
 	return OK;
 }
-Error GlobalConfig::_load_settings(const String p_path) {
+Error ProjectSettings::_load_settings(const String p_path) {
 
 	Error err;
 	FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -403,7 +443,7 @@ Error GlobalConfig::_load_settings(const String p_path) {
 			memdelete(f);
 			return OK;
 		} else if (err != OK) {
-			ERR_PRINTS("GlobalConfig::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
+			ERR_PRINTS("ProjectSettings::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
 			memdelete(f);
 			return err;
 		}
@@ -427,19 +467,19 @@ Error GlobalConfig::_load_settings(const String p_path) {
 	return OK;
 }
 
-int GlobalConfig::get_order(const String &p_name) const {
+int ProjectSettings::get_order(const String &p_name) const {
 
 	ERR_FAIL_COND_V(!props.has(p_name), -1);
 	return props[p_name].order;
 }
 
-void GlobalConfig::set_order(const String &p_name, int p_order) {
+void ProjectSettings::set_order(const String &p_name, int p_order) {
 
 	ERR_FAIL_COND(!props.has(p_name));
 	props[p_name].order = p_order;
 }
 
-void GlobalConfig::set_builtin_order(const String &p_name) {
+void ProjectSettings::set_builtin_order(const String &p_name) {
 
 	ERR_FAIL_COND(!props.has(p_name));
 	if (props[p_name].order >= NO_BUILTIN_ORDER_BASE) {
@@ -447,24 +487,24 @@ void GlobalConfig::set_builtin_order(const String &p_name) {
 	}
 }
 
-void GlobalConfig::clear(const String &p_name) {
+void ProjectSettings::clear(const String &p_name) {
 
 	ERR_FAIL_COND(!props.has(p_name));
 	props.erase(p_name);
 }
 
-Error GlobalConfig::save() {
+Error ProjectSettings::save() {
 
 	return save_custom(get_resource_path() + "/project.godot");
 }
 
-Error GlobalConfig::_save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom) {
+Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom, const String &p_custom_features) {
 
 	Error err;
 	FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
 	if (err != OK) {
 
-		ERR_EXPLAIN("Couldn't save godot.cfb at " + p_file);
+		ERR_EXPLAIN("Couldn't save project.binary at " + p_file);
 		ERR_FAIL_COND_V(err, err)
 	}
 
@@ -481,7 +521,34 @@ Error GlobalConfig::_save_settings_binary(const String &p_file, const Map<String
 		}
 	}
 
-	file->store_32(count); //store how many properties are saved
+	if (p_custom_features != String()) {
+		file->store_32(count + 1);
+		//store how many properties are saved, add one for custom featuers, which must always go first
+		String key = CoreStringNames::get_singleton()->_custom_features;
+		file->store_32(key.length());
+		file->store_string(key);
+
+		int len;
+		Error err = encode_variant(p_custom_features, NULL, len);
+		if (err != OK) {
+			memdelete(file);
+			ERR_FAIL_V(err);
+		}
+
+		Vector<uint8_t> buff;
+		buff.resize(len);
+
+		err = encode_variant(p_custom_features, &buff[0], len);
+		if (err != OK) {
+			memdelete(file);
+			ERR_FAIL_V(err);
+		}
+		file->store_32(len);
+		file->store_buffer(buff.ptr(), buff.size());
+
+	} else {
+		file->store_32(count); //store how many properties are saved
+	}
 
 	for (Map<String, List<String> >::Element *E = props.front(); E; E = E->next()) {
 
@@ -523,7 +590,7 @@ Error GlobalConfig::_save_settings_binary(const String &p_file, const Map<String
 	return OK;
 }
 
-Error GlobalConfig::_save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom) {
+Error ProjectSettings::_save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom, const String &p_custom_features) {
 
 	Error err;
 	FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
@@ -534,6 +601,8 @@ Error GlobalConfig::_save_settings_text(const String &p_file, const Map<String,
 	}
 
 	file->store_string("config_version=" + itos(FORMAT_VERSION) + "\n");
+	if (p_custom_features != String())
+		file->store_string("_custom_featores=\"" + p_custom_features + "\"\n");
 
 	for (Map<String, List<String> >::Element *E = props.front(); E; E = E->next()) {
 
@@ -565,12 +634,12 @@ Error GlobalConfig::_save_settings_text(const String &p_file, const Map<String,
 	return OK;
 }
 
-Error GlobalConfig::_save_custom_bnd(const String &p_file) { // add other params as dictionary and array?
+Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other params as dictionary and array?
 
 	return save_custom(p_file);
 };
 
-Error GlobalConfig::save_custom(const String &p_path, const CustomMap &p_custom, const Set<String> &p_ignore_masks) {
+Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features) {
 
 	ERR_FAIL_COND_V(p_path == "", ERR_INVALID_PARAMETER);
 
@@ -586,19 +655,6 @@ Error GlobalConfig::save_custom(const String &p_path, const CustomMap &p_custom,
 		if (p_custom.has(G->key()))
 			continue;
 
-		bool discard = false;
-
-		for (const Set<String>::Element *E = p_ignore_masks.front(); E; E = E->next()) {
-
-			if (String(G->key()).match(E->get())) {
-				discard = true;
-				break;
-			}
-		}
-
-		if (discard)
-			continue;
-
 		_VCSort vc;
 		vc.name = G->key(); //*k;
 		vc.order = v->order;
@@ -639,10 +695,20 @@ Error GlobalConfig::save_custom(const String &p_path, const CustomMap &p_custom,
 		props[category].push_back(name);
 	}
 
+	String custom_features;
+
+	for (int i = 0; i < p_custom_features.size(); i++) {
+		if (i > 0)
+			custom_features += ",";
+
+		String f = p_custom_features[i].strip_edges().replace("\"", "");
+		custom_features += f;
+	}
+
 	if (p_path.ends_with(".godot"))
-		return _save_settings_text(p_path, props, p_custom);
-	else if (p_path.ends_with(".cfb"))
-		return _save_settings_binary(p_path, props, p_custom);
+		return _save_settings_text(p_path, props, p_custom, custom_features);
+	else if (p_path.ends_with(".binary"))
+		return _save_settings_binary(p_path, props, p_custom, custom_features);
 	else {
 
 		ERR_EXPLAIN("Unknown config file format: " + p_path);
@@ -695,24 +761,24 @@ Error GlobalConfig::save_custom(const String &p_path, const CustomMap &p_custom,
 Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default) {
 
 	Variant ret;
-	if (GlobalConfig::get_singleton()->has(p_var)) {
-		ret = GlobalConfig::get_singleton()->get(p_var);
+	if (ProjectSettings::get_singleton()->has(p_var)) {
+		ret = ProjectSettings::get_singleton()->get(p_var);
 	} else {
-		GlobalConfig::get_singleton()->set(p_var, p_default);
+		ProjectSettings::get_singleton()->set(p_var, p_default);
 		ret = p_default;
 	}
-	GlobalConfig::get_singleton()->set_initial_value(p_var, p_default);
-	GlobalConfig::get_singleton()->set_builtin_order(p_var);
+	ProjectSettings::get_singleton()->set_initial_value(p_var, p_default);
+	ProjectSettings::get_singleton()->set_builtin_order(p_var);
 	return ret;
 }
 
-void GlobalConfig::add_singleton(const Singleton &p_singleton) {
+void ProjectSettings::add_singleton(const Singleton &p_singleton) {
 
 	singletons.push_back(p_singleton);
 	singleton_ptrs[p_singleton.name] = p_singleton.ptr;
 }
 
-Object *GlobalConfig::get_singleton_object(const String &p_name) const {
+Object *ProjectSettings::get_singleton_object(const String &p_name) const {
 
 	const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
 	if (!E)
@@ -721,21 +787,21 @@ Object *GlobalConfig::get_singleton_object(const String &p_name) const {
 		return E->get();
 };
 
-bool GlobalConfig::has_singleton(const String &p_name) const {
+bool ProjectSettings::has_singleton(const String &p_name) const {
 
 	return get_singleton_object(p_name) != NULL;
 };
 
-void GlobalConfig::get_singletons(List<Singleton> *p_singletons) {
+void ProjectSettings::get_singletons(List<Singleton> *p_singletons) {
 
 	for (List<Singleton>::Element *E = singletons.front(); E; E = E->next())
 		p_singletons->push_back(E->get());
 }
 
-Vector<String> GlobalConfig::get_optimizer_presets() const {
+Vector<String> ProjectSettings::get_optimizer_presets() const {
 
 	List<PropertyInfo> pi;
-	GlobalConfig::get_singleton()->get_property_list(&pi);
+	ProjectSettings::get_singleton()->get_property_list(&pi);
 	Vector<String> names;
 
 	for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
@@ -750,7 +816,7 @@ Vector<String> GlobalConfig::get_optimizer_presets() const {
 	return names;
 }
 
-void GlobalConfig::_add_property_info_bind(const Dictionary &p_info) {
+void ProjectSettings::_add_property_info_bind(const Dictionary &p_info) {
 
 	ERR_FAIL_COND(!p_info.has("name"));
 	ERR_FAIL_COND(!p_info.has("type"));
@@ -769,24 +835,24 @@ void GlobalConfig::_add_property_info_bind(const Dictionary &p_info) {
 	set_custom_property_info(pinfo.name, pinfo);
 }
 
-void GlobalConfig::set_custom_property_info(const String &p_prop, const PropertyInfo &p_info) {
+void ProjectSettings::set_custom_property_info(const String &p_prop, const PropertyInfo &p_info) {
 
 	ERR_FAIL_COND(!props.has(p_prop));
 	custom_prop_info[p_prop] = p_info;
 	custom_prop_info[p_prop].name = p_prop;
 }
 
-void GlobalConfig::set_disable_platform_override(bool p_disable) {
+void ProjectSettings::set_disable_feature_overrides(bool p_disable) {
 
-	disable_platform_override = p_disable;
+	disable_feature_overrides = p_disable;
 }
 
-bool GlobalConfig::is_using_datapack() const {
+bool ProjectSettings::is_using_datapack() const {
 
 	return using_datapack;
 }
 
-bool GlobalConfig::property_can_revert(const String &p_name) {
+bool ProjectSettings::property_can_revert(const String &p_name) {
 
 	if (!props.has(p_name))
 		return false;
@@ -794,7 +860,7 @@ bool GlobalConfig::property_can_revert(const String &p_name) {
 	return props[p_name].initial != props[p_name].variant;
 }
 
-Variant GlobalConfig::property_get_revert(const String &p_name) {
+Variant ProjectSettings::property_get_revert(const String &p_name) {
 
 	if (!props.has(p_name))
 		return Variant();
@@ -802,32 +868,32 @@ Variant GlobalConfig::property_get_revert(const String &p_name) {
 	return props[p_name].initial;
 }
 
-void GlobalConfig::_bind_methods() {
-
-	ClassDB::bind_method(D_METHOD("has", "name"), &GlobalConfig::has);
-	ClassDB::bind_method(D_METHOD("set_order", "name", "pos"), &GlobalConfig::set_order);
-	ClassDB::bind_method(D_METHOD("get_order", "name"), &GlobalConfig::get_order);
-	ClassDB::bind_method(D_METHOD("set_initial_value", "name", "value"), &GlobalConfig::set_initial_value);
-	ClassDB::bind_method(D_METHOD("add_property_info", "hint"), &GlobalConfig::_add_property_info_bind);
-	ClassDB::bind_method(D_METHOD("clear", "name"), &GlobalConfig::clear);
-	ClassDB::bind_method(D_METHOD("localize_path", "path"), &GlobalConfig::localize_path);
-	ClassDB::bind_method(D_METHOD("globalize_path", "path"), &GlobalConfig::globalize_path);
-	ClassDB::bind_method(D_METHOD("save"), &GlobalConfig::save);
-	ClassDB::bind_method(D_METHOD("has_singleton", "name"), &GlobalConfig::has_singleton);
-	ClassDB::bind_method(D_METHOD("get_singleton", "name"), &GlobalConfig::get_singleton_object);
-	ClassDB::bind_method(D_METHOD("load_resource_pack", "pack"), &GlobalConfig::_load_resource_pack);
-	ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &GlobalConfig::property_can_revert);
-	ClassDB::bind_method(D_METHOD("property_get_revert:Variant", "name"), &GlobalConfig::property_get_revert);
-
-	ClassDB::bind_method(D_METHOD("save_custom", "file"), &GlobalConfig::_save_custom_bnd);
+void ProjectSettings::_bind_methods() {
+
+	ClassDB::bind_method(D_METHOD("has", "name"), &ProjectSettings::has);
+	ClassDB::bind_method(D_METHOD("set_order", "name", "pos"), &ProjectSettings::set_order);
+	ClassDB::bind_method(D_METHOD("get_order", "name"), &ProjectSettings::get_order);
+	ClassDB::bind_method(D_METHOD("set_initial_value", "name", "value"), &ProjectSettings::set_initial_value);
+	ClassDB::bind_method(D_METHOD("add_property_info", "hint"), &ProjectSettings::_add_property_info_bind);
+	ClassDB::bind_method(D_METHOD("clear", "name"), &ProjectSettings::clear);
+	ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
+	ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
+	ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
+	ClassDB::bind_method(D_METHOD("has_singleton", "name"), &ProjectSettings::has_singleton);
+	ClassDB::bind_method(D_METHOD("get_singleton", "name"), &ProjectSettings::get_singleton_object);
+	ClassDB::bind_method(D_METHOD("load_resource_pack", "pack"), &ProjectSettings::_load_resource_pack);
+	ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert);
+	ClassDB::bind_method(D_METHOD("property_get_revert:Variant", "name"), &ProjectSettings::property_get_revert);
+
+	ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);
 }
 
-GlobalConfig::GlobalConfig() {
+ProjectSettings::ProjectSettings() {
 
 	singleton = this;
 	last_order = NO_BUILTIN_ORDER_BASE;
 	last_builtin_order = 0;
-	disable_platform_override = false;
+	disable_feature_overrides = false;
 	registering_order = true;
 
 	Array va;
@@ -950,6 +1016,8 @@ GlobalConfig::GlobalConfig() {
 	custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
 	custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
 	custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
+	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("rendering/quality/intended_usage/framebuffer_mode", 2);
 
 	GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
 
@@ -964,7 +1032,7 @@ GlobalConfig::GlobalConfig() {
 	using_datapack = false;
 }
 
-GlobalConfig::~GlobalConfig() {
+ProjectSettings::~ProjectSettings() {
 
 	singleton = NULL;
 }

+ 16 - 14
core/global_config.h → core/project_settings.h

@@ -37,9 +37,9 @@
 	@author Juan Linietsky <[email protected]>
 */
 
-class GlobalConfig : public Object {
+class ProjectSettings : public Object {
 
-	GDCLASS(GlobalConfig, Object);
+	GDCLASS(ProjectSettings, Object);
 	_THREAD_SAFE_CLASS_
 
 public:
@@ -53,13 +53,12 @@ public:
 			ptr = p_ptr;
 		}
 	};
-
-protected:
 	enum {
 		//properties that are not for built in values begin from this value, so builtin ones are displayed first
 		NO_BUILTIN_ORDER_BASE = 1 << 16
 	};
 
+protected:
 	struct VariantContainer {
 		int order;
 		bool persist;
@@ -88,21 +87,24 @@ protected:
 	Map<StringName, VariantContainer> props;
 	String resource_path;
 	Map<StringName, PropertyInfo> custom_prop_info;
-	bool disable_platform_override;
+	bool disable_feature_overrides;
 	bool using_datapack;
 	List<String> input_presets;
 
+	Set<String> custom_features;
+	Map<StringName, StringName> feature_overrides;
+
 	bool _set(const StringName &p_name, const Variant &p_value);
 	bool _get(const StringName &p_name, Variant &r_ret) const;
 	void _get_property_list(List<PropertyInfo> *p_list) const;
 
-	static GlobalConfig *singleton;
+	static ProjectSettings *singleton;
 
 	Error _load_settings(const String p_path);
 	Error _load_settings_binary(const String p_path);
 
-	Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap());
-	Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap());
+	Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String());
+	Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String());
 
 	List<Singleton> singletons;
 	Map<StringName, Object *> singleton_ptrs;
@@ -127,7 +129,7 @@ public:
 
 	String get_resource_path() const;
 
-	static GlobalConfig *get_singleton();
+	static ProjectSettings *get_singleton();
 
 	void clear(const String &p_name);
 	int get_order(const String &p_name) const;
@@ -136,7 +138,7 @@ public:
 
 	Error setup(const String &p_path, const String &p_main_pack);
 
-	Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Set<String> &p_ignore_masks = Set<String>());
+	Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Vector<String> &p_custom_features = Vector<String>());
 	Error save();
 	void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info);
 
@@ -149,7 +151,7 @@ public:
 
 	List<String> get_input_presets() const { return input_presets; }
 
-	void set_disable_platform_override(bool p_disable);
+	void set_disable_feature_overrides(bool p_disable);
 	Object *get_singleton_object(const String &p_name) const;
 
 	void register_global_defaults();
@@ -158,13 +160,13 @@ public:
 
 	void set_registering_order(bool p_registering);
 
-	GlobalConfig();
-	~GlobalConfig();
+	ProjectSettings();
+	~ProjectSettings();
 };
 
 //not a macro any longer
 Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default);
 #define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value)
-#define GLOBAL_GET(m_var) GlobalConfig::get_singleton()->get(m_var)
+#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var)
 
 #endif

+ 13 - 13
core/register_core_types.cpp

@@ -36,7 +36,7 @@
 #include "core_string_names.h"
 #include "func_ref.h"
 #include "geometry.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "input_map.h"
 #include "io/config_file.h"
 #include "io/http_client.h"
@@ -177,18 +177,18 @@ void register_core_settings() {
 
 void register_core_singletons() {
 
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("GlobalConfig", GlobalConfig::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("IP", IP::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("Geometry", _Geometry::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("ResourceLoader", _ResourceLoader::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("ResourceSaver", _ResourceSaver::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("OS", _OS::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("Engine", _Engine::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("ClassDB", _classdb));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("Marshalls", _Marshalls::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("TranslationServer", TranslationServer::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("Input", Input::get_singleton()));
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("InputMap", InputMap::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ProjectSettings", ProjectSettings::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("IP", IP::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Geometry", _Geometry::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ResourceLoader", _ResourceLoader::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ResourceSaver", _ResourceSaver::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("OS", _OS::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Engine", _Engine::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ClassDB", _classdb));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Marshalls", _Marshalls::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("TranslationServer", TranslationServer::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Input", Input::get_singleton()));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("InputMap", InputMap::get_singleton()));
 }
 
 void unregister_core_types() {

+ 4 - 4
core/script_debugger_remote.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "script_debugger_remote.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/ip.h"
 #include "os/input.h"
 #include "os/os.h"
@@ -130,7 +130,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
 		ERR_FAIL();
 	}
 
-	OS::get_singleton()->enable_for_stealing_focus(GlobalConfig::get_singleton()->get("editor_pid"));
+	OS::get_singleton()->enable_for_stealing_focus(ProjectSettings::get_singleton()->get("editor_pid"));
 
 	packet_peer_stream->put_var("debug_enter");
 	packet_peer_stream->put_var(2);
@@ -952,7 +952,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
 	phl.userdata = this;
 	add_print_handler(&phl);
 	requested_quit = false;
-	performance = GlobalConfig::get_singleton()->get_singleton_object("Performance");
+	performance = ProjectSettings::get_singleton()->get_singleton_object("Performance");
 	last_perf_time = 0;
 	poll_every = 0;
 	request_scene_tree = NULL;
@@ -967,7 +967,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
 	eh.userdata = this;
 	add_error_handler(&eh);
 
-	profile_info.resize(CLAMP(int(GlobalConfig::get_singleton()->get("debug/settings/profiler/max_functions")), 128, 65535));
+	profile_info.resize(CLAMP(int(ProjectSettings::get_singleton()->get("debug/settings/profiler/max_functions")), 128, 65535));
 	profile_info_ptrs.resize(profile_info.size());
 	profiling = false;
 	max_frame_functions = 16;

+ 4 - 4
core/translation.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "translation.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "os/os.h"
 
@@ -1053,8 +1053,8 @@ TranslationServer *TranslationServer::singleton = NULL;
 
 bool TranslationServer::_load_translations(const String &p_from) {
 
-	if (GlobalConfig::get_singleton()->has(p_from)) {
-		PoolVector<String> translations = GlobalConfig::get_singleton()->get(p_from);
+	if (ProjectSettings::get_singleton()->has(p_from)) {
+		PoolVector<String> translations = ProjectSettings::get_singleton()->get(p_from);
 
 		int tcount = translations.size();
 
@@ -1095,7 +1095,7 @@ void TranslationServer::setup() {
 			options += locale_list[idx];
 			idx++;
 		}
-		GlobalConfig::get_singleton()->set_custom_property_info("locale/fallback", PropertyInfo(Variant::STRING, "locale/fallback", PROPERTY_HINT_ENUM, options));
+		ProjectSettings::get_singleton()->set_custom_property_info("locale/fallback", PropertyInfo(Variant::STRING, "locale/fallback", PROPERTY_HINT_ENUM, options));
 	}
 #endif
 	//load translations

+ 2 - 2
doc/base/classes.xml

@@ -741,7 +741,7 @@
 		<member name="Geometry" type="Geometry" setter="" getter="" brief="">
 			[Geometry] singleton
 		</member>
-		<member name="GlobalConfig" type="GlobalConfig" setter="" getter="" brief="">
+		<member name="ProjectSettings" type="ProjectSettings" setter="" getter="" brief="">
 		</member>
 		<member name="IP" type="IP" setter="" getter="" brief="">
 			[IP] singleton
@@ -17682,7 +17682,7 @@
 		</constant>
 	</constants>
 </class>
-<class name="GlobalConfig" inherits="Object" category="Core">
+<class name="ProjectSettings" inherits="Object" category="Core">
 	<brief_description>
 		Contains global variables accessible from everywhere.
 	</brief_description>

+ 1 - 1
drivers/alsa/audio_driver_alsa.cpp

@@ -31,7 +31,7 @@
 
 #ifdef ALSA_ENABLED
 
-#include "global_config.h"
+#include "project_settings.h"
 
 #include <errno.h>
 

+ 4 - 4
drivers/gles2/rasterizer_gles2.cpp

@@ -31,7 +31,7 @@
 
 #include "rasterizer_gles2.h"
 #include "gl_context/context_gl.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 #include "servers/visual/particle_system_sw.h"
 #include "servers/visual/shader_language.h"
@@ -3942,7 +3942,7 @@ void RasterizerGLES2::begin_frame() {
 //fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
 #ifdef TOOLS_ENABLED
 	canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/use_2d_pixel_snap", false));
-	shadow_filter = ShadowFilterTechnique(int(GlobalConfig::get_singleton()->get("rasterizer/shadow_filter")));
+	shadow_filter = ShadowFilterTechnique(int(ProjectSettings::get_singleton()->get("rasterizer/shadow_filter")));
 #endif
 
 	canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF5, shadow_filter == SHADOW_FILTER_PCF5);
@@ -6819,7 +6819,7 @@ void RasterizerGLES2::end_scene() {
 				if (current_env->bg_mode == VS::ENV_BG_COLOR)
 					bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR];
 				else
-					bgcolor = GlobalConfig::get_singleton()->get("render/default_clear_color");
+					bgcolor = ProjectSettings::get_singleton()->get("render/default_clear_color");
 				bgcolor = _convert_color(bgcolor);
 				float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0;
 				glClearColor(bgcolor.r, bgcolor.g, bgcolor.b, a);
@@ -10718,7 +10718,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays, bool p_keep_ram_copy, b
 	fragment_lighting = GLOBAL_DEF("rasterizer/use_fragment_lighting", true);
 	read_depth_supported = true; //todo check for extension
 	shadow_filter = ShadowFilterTechnique((int)(GLOBAL_DEF("rasterizer/shadow_filter", SHADOW_FILTER_PCF5)));
-	GlobalConfig::get_singleton()->set_custom_property_info("rasterizer/shadow_filter", PropertyInfo(Variant::INT, "rasterizer/shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13,ESM"));
+	ProjectSettings::get_singleton()->set_custom_property_info("rasterizer/shadow_filter", PropertyInfo(Variant::INT, "rasterizer/shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13,ESM"));
 	use_fp16_fb = bool(GLOBAL_DEF("rasterizer/fp16_framebuffer", true));
 	use_shadow_mapping = true;
 	use_fast_texture_filter = !bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter", true));

+ 1 - 1
drivers/gles3/rasterizer_canvas_gles3.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "rasterizer_canvas_gles3.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 #include "rasterizer_scene_gles3.h"
 #include "servers/visual/visual_server_raster.h"

+ 1 - 1
drivers/gles3/rasterizer_gles3.cpp

@@ -30,7 +30,7 @@
 #include "rasterizer_gles3.h"
 
 #include "gl_context/context_gl.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 #include <string.h>
 RasterizerStorage *RasterizerGLES3::get_storage() {

+ 8 - 10
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -29,8 +29,8 @@
 /*************************************************************************/
 #include "rasterizer_scene_gles3.h"
 
-#include "global_config.h"
 #include "os/os.h"
+#include "project_settings.h"
 #include "rasterizer_canvas_gles3.h"
 
 #ifndef GLES_OVER_GL
@@ -4779,8 +4779,6 @@ void RasterizerSceneGLES3::initialize() {
 		state.scene_shader.add_custom_define("#define MAX_SKELETON_BONES " + itos(state.max_skeleton_bones) + "\n");
 	}
 
-	GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1);
-	GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
 	shadow_filter_mode = SHADOW_FILTER_NEAREST;
 
 	{ //reflection cubemaps
@@ -4872,9 +4870,9 @@ void RasterizerSceneGLES3::initialize() {
 
 	{
 		GLOBAL_DEF("rendering/quality/subsurface_scattering/quality", 1);
-		GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/quality", PROPERTY_HINT_ENUM, "Low,Medium,High"));
+		ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/quality", PROPERTY_HINT_ENUM, "Low,Medium,High"));
 		GLOBAL_DEF("rendering/quality/subsurface_scattering/scale", 1.0);
-		GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/scale", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/scale", PROPERTY_HINT_RANGE, "0.01,8,0.01"));
+		ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/scale", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/scale", PROPERTY_HINT_RANGE, "0.01,8,0.01"));
 		GLOBAL_DEF("rendering/quality/subsurface_scattering/follow_surface", false);
 
 		GLOBAL_DEF("rendering/quality/voxel_cone_tracing/high_quality", true);
@@ -4916,12 +4914,12 @@ void RasterizerSceneGLES3::initialize() {
 
 void RasterizerSceneGLES3::iteration() {
 
-	shadow_filter_mode = ShadowFilterMode(int(GlobalConfig::get_singleton()->get("rendering/quality/shadows/filter_mode")));
-	subsurface_scatter_follow_surface = GlobalConfig::get_singleton()->get("rendering/quality/subsurface_scattering/follow_surface");
-	subsurface_scatter_quality = SubSurfaceScatterQuality(int(GlobalConfig::get_singleton()->get("rendering/quality/subsurface_scattering/quality")));
-	subsurface_scatter_size = GlobalConfig::get_singleton()->get("rendering/quality/subsurface_scattering/scale");
+	shadow_filter_mode = ShadowFilterMode(int(ProjectSettings::get_singleton()->get("rendering/quality/shadows/filter_mode")));
+	subsurface_scatter_follow_surface = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/follow_surface");
+	subsurface_scatter_quality = SubSurfaceScatterQuality(int(ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/quality")));
+	subsurface_scatter_size = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/scale");
 
-	state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GlobalConfig::get_singleton()->get("rendering/quality/voxel_cone_tracing/high_quality"));
+	state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, ProjectSettings::get_singleton()->get("rendering/quality/voxel_cone_tracing/high_quality"));
 }
 
 void RasterizerSceneGLES3::finalize() {

+ 4 - 4
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "rasterizer_storage_gles3.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "rasterizer_canvas_gles3.h"
 #include "rasterizer_scene_gles3.h"
 
@@ -6848,7 +6848,7 @@ void RasterizerStorageGLES3::initialize() {
 	}
 
 	config.shrink_textures_x2 = false;
-	config.use_fast_texture_filter = int(GlobalConfig::get_singleton()->get("rendering/quality/filters/use_nearest_mipmap_filter"));
+	config.use_fast_texture_filter = int(ProjectSettings::get_singleton()->get("rendering/quality/filters/use_nearest_mipmap_filter"));
 	config.use_anisotropic_filter = config.extensions.has("rendering/quality/filters/anisotropic_filter_level");
 
 	config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
@@ -6872,7 +6872,7 @@ void RasterizerStorageGLES3::initialize() {
 	config.use_anisotropic_filter = config.extensions.has("GL_EXT_texture_filter_anisotropic");
 	if (config.use_anisotropic_filter) {
 		glGetFloatv(_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &config.anisotropic_level);
-		config.anisotropic_level = MIN(int(GlobalConfig::get_singleton()->get("rendering/quality/anisotropic_filter_level")), config.anisotropic_level);
+		config.anisotropic_level = MIN(int(ProjectSettings::get_singleton()->get("rendering/quality/anisotropic_filter_level")), config.anisotropic_level);
 	}
 
 	frame.clear_request = false;
@@ -7009,7 +7009,7 @@ void RasterizerStorageGLES3::initialize() {
 	frame.current_rt = NULL;
 	config.keep_original_textures = false;
 	config.generate_wireframes = false;
-	config.use_texture_array_environment = GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
+	config.use_texture_array_environment = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
 }
 
 void RasterizerStorageGLES3::finalize() {

+ 1 - 1
drivers/png/resource_saver_png.cpp

@@ -30,7 +30,7 @@
 #include "resource_saver_png.h"
 
 #include "core/image.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/file_access.h"
 #include "scene/resources/texture.h"
 

+ 1 - 1
drivers/pulseaudio/audio_driver_pulseaudio.cpp

@@ -33,7 +33,7 @@
 
 #include <pulse/error.h>
 
-#include "global_config.h"
+#include "project_settings.h"
 
 Error AudioDriverPulseAudio::init() {
 

+ 1 - 1
drivers/rtaudio/audio_driver_rtaudio.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "audio_driver_rtaudio.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 
 #ifdef RTAUDIO_ENABLED

+ 3 - 8
drivers/unix/os_unix.cpp

@@ -53,7 +53,7 @@
 #if defined(__FreeBSD__) || defined(__OpenBSD__)
 #include <sys/param.h>
 #endif
-#include "global_config.h"
+#include "project_settings.h"
 #include <assert.h>
 #include <dlfcn.h>
 #include <errno.h>
@@ -494,7 +494,7 @@ String OS_Unix::get_data_dir() const {
 
 		if (has_environment("HOME")) {
 
-			bool use_godot = GlobalConfig::get_singleton()->get("application/config/use_shared_user_dir");
+			bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir");
 			if (use_godot)
 				return get_environment("HOME") + "/.godot/app_userdata/" + an;
 			else
@@ -502,12 +502,7 @@ String OS_Unix::get_data_dir() const {
 		}
 	}
 
-	return GlobalConfig::get_singleton()->get_resource_path();
-}
-
-bool OS_Unix::check_feature_support(const String &p_feature) {
-
-	return VisualServer::get_singleton()->has_os_feature(p_feature);
+	return ProjectSettings::get_singleton()->get_resource_path();
 }
 
 String OS_Unix::get_installed_templates_path() const {

+ 0 - 2
drivers/unix/os_unix.h

@@ -117,8 +117,6 @@ public:
 	virtual String get_executable_path() const;
 	virtual String get_data_dir() const;
 
-	virtual bool check_feature_support(const String &p_feature);
-
 	//virtual void run( MainLoop * p_main_loop );
 };
 

+ 1 - 1
drivers/xaudio2/audio_driver_xaudio2.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "audio_driver_xaudio2.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 
 const char *AudioDriverXAudio2::get_name() const {

+ 2 - 2
editor/asset_library_editor_plugin.cpp

@@ -1228,8 +1228,8 @@ void EditorAssetLibrary::_asset_open() {
 
 void EditorAssetLibrary::_manage_plugins() {
 
-	ProjectSettings::get_singleton()->popup_project_settings();
-	ProjectSettings::get_singleton()->set_plugins_page();
+	ProjectSettingsEditor::get_singleton()->popup_project_settings();
+	ProjectSettingsEditor::get_singleton()->set_plugins_page();
 }
 
 void EditorAssetLibrary::_install_external_asset(String p_zip_path, String p_title) {

+ 4 - 4
editor/collada/collada.cpp

@@ -306,7 +306,7 @@ void Collada::_parse_image(XMLParser &parser) {
 		String path = parser.get_attribute_value("source").strip_edges();
 		if (path.find("://") == -1 && path.is_rel_path()) {
 			// path is relative to file being loaded, so convert to a resource path
-			image.path = GlobalConfig::get_singleton()->localize_path(state.local_path.get_base_dir() + "/" + path.percent_decode());
+			image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir() + "/" + path.percent_decode());
 		}
 	} else {
 
@@ -323,11 +323,11 @@ void Collada::_parse_image(XMLParser &parser) {
 
 					if (path.find("://") == -1 && path.is_rel_path()) {
 						// path is relative to file being loaded, so convert to a resource path
-						path = GlobalConfig::get_singleton()->localize_path(state.local_path.get_base_dir() + "/" + path);
+						path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir() + "/" + path);
 
 					} else if (path.find("file:///") == 0) {
 						path = path.replace_first("file:///", "");
-						path = GlobalConfig::get_singleton()->localize_path(path);
+						path = ProjectSettings::get_singleton()->localize_path(path);
 					}
 
 					image.path = path;
@@ -2556,7 +2556,7 @@ Error Collada::load(const String &p_path, int p_flags) {
 	Error err = parser.open(p_path);
 	ERR_FAIL_COND_V(err, err);
 
-	state.local_path = GlobalConfig::get_singleton()->localize_path(p_path);
+	state.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 	state.import_flags = p_flags;
 	/* Skip headers */
 	err = OK;

+ 1 - 1
editor/collada/collada.h

@@ -32,7 +32,7 @@
 #ifndef COLLADA_H
 #define COLLADA_H
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/xml_parser.h"
 #include "map.h"
 #include "scene/resources/material.h"

+ 5 - 5
editor/doc/doc_data.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "doc_data.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "global_constants.h"
 #include "io/compression.h"
 #include "io/marshalls.h"
@@ -568,14 +568,14 @@ void DocData::generate(bool p_basic_types) {
 			c.constants.push_back(cd);
 		}
 
-		List<GlobalConfig::Singleton> singletons;
-		GlobalConfig::get_singleton()->get_singletons(&singletons);
+		List<ProjectSettings::Singleton> singletons;
+		ProjectSettings::get_singleton()->get_singletons(&singletons);
 
 		//servers (this is kind of hackish)
-		for (List<GlobalConfig::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
+		for (List<ProjectSettings::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
 
 			PropertyDoc pd;
-			GlobalConfig::Singleton &s = E->get();
+			ProjectSettings::Singleton &s = E->get();
 			pd.name = s.name;
 			pd.type = s.ptr->get_class();
 			while (String(ClassDB::get_parent_class(pd.type)) != "Object")

+ 38 - 38
editor/editor_autoload_settings.cpp

@@ -30,7 +30,7 @@
 #include "editor_autoload_settings.h"
 
 #include "editor_node.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "global_constants.h"
 
 #define PREVIEW_LIST_MAX_SIZE 10
@@ -115,12 +115,12 @@ void EditorAutoloadSettings::_autoload_add() {
 	UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
 
 	undo_redo->create_action(TTR("Add AutoLoad"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), name, "*" + path);
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), name, "*" + path);
 
-	if (GlobalConfig::get_singleton()->has(name)) {
-		undo_redo->add_undo_property(GlobalConfig::get_singleton(), name, GlobalConfig::get_singleton()->get(name));
+	if (ProjectSettings::get_singleton()->has(name)) {
+		undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, ProjectSettings::get_singleton()->get(name));
 	} else {
-		undo_redo->add_undo_property(GlobalConfig::get_singleton(), name, Variant());
+		undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, Variant());
 	}
 
 	undo_redo->add_do_method(this, "update_autoload");
@@ -169,7 +169,7 @@ void EditorAutoloadSettings::_autoload_edited() {
 			return;
 		}
 
-		if (GlobalConfig::get_singleton()->has("autoload/" + name)) {
+		if (ProjectSettings::get_singleton()->has("autoload/" + name)) {
 			ti->set_text(0, old_name);
 			EditorNode::get_singleton()->show_warning(vformat(TTR("Autoload '%s' already exists!"), name));
 			return;
@@ -179,18 +179,18 @@ void EditorAutoloadSettings::_autoload_edited() {
 
 		name = "autoload/" + name;
 
-		int order = GlobalConfig::get_singleton()->get_order(selected_autoload);
-		String path = GlobalConfig::get_singleton()->get(selected_autoload);
+		int order = ProjectSettings::get_singleton()->get_order(selected_autoload);
+		String path = ProjectSettings::get_singleton()->get(selected_autoload);
 
 		undo_redo->create_action(TTR("Rename Autoload"));
 
-		undo_redo->add_do_property(GlobalConfig::get_singleton(), name, path);
-		undo_redo->add_do_method(GlobalConfig::get_singleton(), "set_order", name, order);
-		undo_redo->add_do_method(GlobalConfig::get_singleton(), "clear", selected_autoload);
+		undo_redo->add_do_property(ProjectSettings::get_singleton(), name, path);
+		undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", name, order);
+		undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", selected_autoload);
 
-		undo_redo->add_undo_property(GlobalConfig::get_singleton(), selected_autoload, path);
-		undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", selected_autoload, order);
-		undo_redo->add_undo_method(GlobalConfig::get_singleton(), "clear", name);
+		undo_redo->add_undo_property(ProjectSettings::get_singleton(), selected_autoload, path);
+		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_autoload, order);
+		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
 
 		undo_redo->add_do_method(this, "update_autoload");
 		undo_redo->add_undo_method(this, "update_autoload");
@@ -207,8 +207,8 @@ void EditorAutoloadSettings::_autoload_edited() {
 		bool checked = ti->is_checked(2);
 		String base = "autoload/" + ti->get_text(0);
 
-		int order = GlobalConfig::get_singleton()->get_order(base);
-		String path = GlobalConfig::get_singleton()->get(base);
+		int order = ProjectSettings::get_singleton()->get_order(base);
+		String path = ProjectSettings::get_singleton()->get(base);
 
 		if (path.begins_with("*"))
 			path = path.substr(1, path.length());
@@ -218,11 +218,11 @@ void EditorAutoloadSettings::_autoload_edited() {
 
 		undo_redo->create_action(TTR("Toggle AutoLoad Globals"));
 
-		undo_redo->add_do_property(GlobalConfig::get_singleton(), base, path);
-		undo_redo->add_undo_property(GlobalConfig::get_singleton(), base, GlobalConfig::get_singleton()->get(base));
+		undo_redo->add_do_property(ProjectSettings::get_singleton(), base, path);
+		undo_redo->add_undo_property(ProjectSettings::get_singleton(), base, ProjectSettings::get_singleton()->get(base));
 
-		undo_redo->add_do_method(GlobalConfig::get_singleton(), "set_order", base, order);
-		undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", base, order);
+		undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", base, order);
+		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", base, order);
 
 		undo_redo->add_do_method(this, "update_autoload");
 		undo_redo->add_undo_method(this, "update_autoload");
@@ -262,16 +262,16 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
 
 			String swap_name = "autoload/" + swap->get_text(0);
 
-			int order = GlobalConfig::get_singleton()->get_order(name);
-			int swap_order = GlobalConfig::get_singleton()->get_order(swap_name);
+			int order = ProjectSettings::get_singleton()->get_order(name);
+			int swap_order = ProjectSettings::get_singleton()->get_order(swap_name);
 
 			undo_redo->create_action(TTR("Move Autoload"));
 
-			undo_redo->add_do_method(GlobalConfig::get_singleton(), "set_order", name, swap_order);
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", name, order);
+			undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", name, swap_order);
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", name, order);
 
-			undo_redo->add_do_method(GlobalConfig::get_singleton(), "set_order", swap_name, order);
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", swap_name, swap_order);
+			undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", swap_name, order);
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", swap_name, swap_order);
 
 			undo_redo->add_do_method(this, "update_autoload");
 			undo_redo->add_undo_method(this, "update_autoload");
@@ -283,15 +283,15 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
 		} break;
 		case BUTTON_DELETE: {
 
-			int order = GlobalConfig::get_singleton()->get_order(name);
+			int order = ProjectSettings::get_singleton()->get_order(name);
 
 			undo_redo->create_action(TTR("Remove Autoload"));
 
-			undo_redo->add_do_property(GlobalConfig::get_singleton(), name, Variant());
+			undo_redo->add_do_property(ProjectSettings::get_singleton(), name, Variant());
 
-			undo_redo->add_undo_property(GlobalConfig::get_singleton(), name, GlobalConfig::get_singleton()->get(name));
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_persisting", name, true);
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", order);
+			undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, ProjectSettings::get_singleton()->get(name));
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_persisting", name, true);
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", order);
 
 			undo_redo->add_do_method(this, "update_autoload");
 			undo_redo->add_undo_method(this, "update_autoload");
@@ -322,7 +322,7 @@ void EditorAutoloadSettings::update_autoload() {
 	TreeItem *root = tree->create_item();
 
 	List<PropertyInfo> props;
-	GlobalConfig::get_singleton()->get_property_list(&props);
+	ProjectSettings::get_singleton()->get_property_list(&props);
 
 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
@@ -332,14 +332,14 @@ void EditorAutoloadSettings::update_autoload() {
 			continue;
 
 		String name = pi.name.get_slice("/", 1);
-		String path = GlobalConfig::get_singleton()->get(pi.name);
+		String path = ProjectSettings::get_singleton()->get(pi.name);
 
 		if (name.empty())
 			continue;
 
 		AutoLoadInfo info;
 		info.name = pi.name;
-		info.order = GlobalConfig::get_singleton()->get_order(pi.name);
+		info.order = ProjectSettings::get_singleton()->get_order(pi.name);
 
 		autoload_cache.push_back(info);
 
@@ -459,7 +459,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
 		move_to_back = true;
 	}
 
-	int order = GlobalConfig::get_singleton()->get_order("autoload/" + name);
+	int order = ProjectSettings::get_singleton()->get_order("autoload/" + name);
 
 	AutoLoadInfo aux;
 	List<AutoLoadInfo>::Element *E = NULL;
@@ -476,7 +476,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
 	orders.resize(autoload_cache.size());
 
 	for (int i = 0; i < autoloads.size(); i++) {
-		aux.order = GlobalConfig::get_singleton()->get_order("autoload/" + autoloads[i]);
+		aux.order = ProjectSettings::get_singleton()->get_order("autoload/" + autoloads[i]);
 
 		List<AutoLoadInfo>::Element *I = autoload_cache.find(aux);
 
@@ -506,8 +506,8 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
 	i = 0;
 
 	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
-		undo_redo->add_do_method(GlobalConfig::get_singleton(), "set_order", E->get().name, orders[i++]);
-		undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", E->get().name, E->get().order);
+		undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", E->get().name, orders[i++]);
+		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", E->get().name, E->get().order);
 	}
 
 	orders.clear();

+ 1 - 1
editor/editor_data.cpp

@@ -31,7 +31,7 @@
 
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "os/dir_access.h"
 #include "os/file_access.h"

+ 68 - 15
editor/editor_export.cpp

@@ -33,13 +33,13 @@
 #include "editor/plugins/script_editor_plugin.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
 #include "io/config_file.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "io/zip_io.h"
 #include "os/dir_access.h"
 #include "os/file_access.h"
+#include "project_settings.h"
 #include "script_language.h"
 #include "version.h"
 
@@ -200,6 +200,17 @@ Vector<String> EditorExportPreset::get_patches() const {
 	return patches;
 }
 
+void EditorExportPreset::set_custom_features(const String &p_custom_features) {
+
+	custom_features = p_custom_features;
+	EditorExport::singleton->save_presets();
+}
+
+String EditorExportPreset::get_custom_features() const {
+
+	return custom_features;
+}
+
 EditorExportPreset::EditorExportPreset() {
 
 	export_filter = EXPORT_ALL_RESOURCES;
@@ -491,9 +502,23 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 
 	//save config!
 
-	String config_file = "godot.cfb";
+	Vector<String> custom_list;
+
+	if (p_preset->get_custom_features() != String()) {
+
+		Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
+
+		for (int i = 0; i < tmp_custom_list.size(); i++) {
+			String f = tmp_custom_list[i].strip_edges();
+			if (f != String()) {
+				custom_list.push_back(f);
+			}
+		}
+	}
+
+	String config_file = "project.binary";
 	String engine_cfb = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp" + config_file;
-	GlobalConfig::get_singleton()->save_custom(engine_cfb);
+	ProjectSettings::get_singleton()->save_custom(engine_cfb, ProjectSettings::CustomMap(), custom_list);
 	Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
 
 	p_func(p_udata, "res://" + config_file, data, idx, total);
@@ -691,6 +716,7 @@ void EditorExport::_save() {
 		config->set_value(section, "name", preset->get_name());
 		config->set_value(section, "platform", preset->get_platform()->get_name());
 		config->set_value(section, "runnable", preset->is_runnable());
+		config->set_value(section, "custom_feaures", preset->get_custom_features());
 		bool save_files = false;
 		switch (preset->get_export_filter()) {
 			case EditorExportPreset::EXPORT_ALL_RESOURCES: {
@@ -823,6 +849,10 @@ void EditorExport::load_config() {
 		preset->set_name(config->get_value(section, "name"));
 		preset->set_runnable(config->get_value(section, "runnable"));
 
+		if (config->has_section_key(section, "custom_features")) {
+			preset->set_custom_features(config->get_value(section, "custom_features"));
+		}
+
 		String export_filter = config->get_value(section, "export_filter");
 
 		bool get_files = false;
@@ -931,6 +961,11 @@ String EditorExportPlatformPC::get_name() const {
 
 	return name;
 }
+
+String EditorExportPlatformPC::get_os_name() const {
+
+	return os_name;
+}
 Ref<Texture> EditorExportPlatformPC::get_logo() const {
 
 	return logo;
@@ -1033,6 +1068,10 @@ void EditorExportPlatformPC::set_name(const String &p_name) {
 	name = p_name;
 }
 
+void EditorExportPlatformPC::set_os_name(const String &p_name) {
+	os_name = p_name;
+}
+
 void EditorExportPlatformPC::set_logo(const Ref<Texture> &p_logo) {
 	logo = p_logo;
 }
@@ -1055,6 +1094,20 @@ void EditorExportPlatformPC::set_debug_32(const String &p_file) {
 	debug_file_32 = p_file;
 }
 
+void EditorExportPlatformPC::add_platform_feature(const String &p_feature) {
+
+	extra_features.insert(p_feature);
+}
+
+void EditorExportPlatformPC::get_platform_features(List<String> *r_features) {
+	r_features->push_back("pc"); //all pcs support "pc"
+	r_features->push_back("s3tc"); //all pcs support "s3tc" compression
+	r_features->push_back(get_os_name()); //OS name is a feature
+	for (Set<String>::Element *E = extra_features.front(); E; E = E->next()) {
+		r_features->push_back(E->get());
+	}
+}
+
 EditorExportPlatformPC::EditorExportPlatformPC() {
 }
 
@@ -1065,7 +1118,6 @@ EditorExportPlatformPC::EditorExportPlatformPC() {
 #include "editor/plugins/script_editor_plugin.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
 #include "io/config_file.h"
 #include "io/md5.h"
 #include "io/resource_loader.h"
@@ -1074,14 +1126,15 @@ EditorExportPlatformPC::EditorExportPlatformPC() {
 #include "io_plugins/editor_texture_import_plugin.h"
 #include "os/dir_access.h"
 #include "os/file_access.h"
+#include "project_settings.h"
 #include "script_language.h"
 #include "version.h"
 
 
 String EditorImportPlugin::validate_source_path(const String& p_path) {
 
-	String gp = GlobalConfig::get_singleton()->globalize_path(p_path);
-	String rp = GlobalConfig::get_singleton()->get_resource_path();
+	String gp = ProjectSettings::get_singleton()->globalize_path(p_path);
+	String rp = ProjectSettings::get_singleton()->get_resource_path();
 	if (!rp.ends_with("/"))
 		rp+="/";
 
@@ -1091,7 +1144,7 @@ String EditorImportPlugin::validate_source_path(const String& p_path) {
 String EditorImportPlugin::expand_source_path(const String& p_path) {
 
 	if (p_path.is_rel_path()) {
-		return GlobalConfig::get_singleton()->get_resource_path().plus_file(p_path).simplify_path();
+		return ProjectSettings::get_singleton()->get_resource_path().plus_file(p_path).simplify_path();
 	} else {
 		return p_path;
 	}
@@ -1766,7 +1819,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
 		{
 			MD5_CTX ctx;
 			MD5Init(&ctx);
-			String path = GlobalConfig::get_singleton()->get_resource_path()+"::"+String(E->get())+"::"+get_name();
+			String path = ProjectSettings::get_singleton()->get_resource_path()+"::"+String(E->get())+"::"+get_name();
 			MD5Update(&ctx,(unsigned char*)path.utf8().get_data(),path.utf8().length());
 			MD5Final(&ctx);
 			md5 = String::md5(ctx.digest);
@@ -1875,11 +1928,11 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
 
 			int flags=0;
 
-			if (GlobalConfig::get_singleton()->get("image_loader/filter"))
+			if (ProjectSettings::get_singleton()->get("image_loader/filter"))
 				flags|=EditorTextureImportPlugin::IMAGE_FLAG_FILTER;
-			if (!GlobalConfig::get_singleton()->get("image_loader/gen_mipmaps"))
+			if (!ProjectSettings::get_singleton()->get("image_loader/gen_mipmaps"))
 				flags|=EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS;
-			if (!GlobalConfig::get_singleton()->get("image_loader/repeat"))
+			if (!ProjectSettings::get_singleton()->get("image_loader/repeat"))
 				flags|=EditorTextureImportPlugin::IMAGE_FLAG_REPEAT;
 
 			flags|=EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA;
@@ -1988,7 +2041,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
 	StringName engine_cfg="res://project.godot";
 	StringName boot_splash;
 	{
-		String splash=GlobalConfig::get_singleton()->get("application/boot_splash"); //avoid splash from being converted
+		String splash=ProjectSettings::get_singleton()->get("application/boot_splash"); //avoid splash from being converted
 		splash=splash.strip_edges();
 		if (splash!=String()) {
 			if (!splash.begins_with("res://"))
@@ -1999,7 +2052,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
 	}
 	StringName custom_cursor;
 	{
-		String splash=GlobalConfig::get_singleton()->get("display/custom_mouse_cursor"); //avoid splash from being converted
+		String splash=ProjectSettings::get_singleton()->get("display/custom_mouse_cursor"); //avoid splash from being converted
 		splash=splash.strip_edges();
 		if (splash!=String()) {
 			if (!splash.begins_with("res://"))
@@ -2083,9 +2136,9 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
 
 		}
 
-		String remap_file="godot.cfb";
+		String remap_file="project.binary";
 		String engine_cfb =EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp"+remap_file;
-		GlobalConfig::get_singleton()->save_custom(engine_cfb,custom);
+		ProjectSettings::get_singleton()->save_custom(engine_cfb,custom);
 		Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
 
 		Error err = p_func(p_udata,"res://"+remap_file,data,counter,files.size());

+ 17 - 1
editor/editor_export.h

@@ -70,6 +70,8 @@ private:
 
 	String name;
 
+	String custom_features;
+
 protected:
 	bool _set(const StringName &p_name, const Variant &p_value);
 	bool _get(const StringName &p_name, Variant &r_ret) const;
@@ -107,6 +109,9 @@ public:
 	void remove_patch(int p_idx);
 	Vector<String> get_patches() const;
 
+	void set_custom_features(const String &p_custom_features);
+	String get_custom_features() const;
+
 	const List<PropertyInfo> &get_properties() const { return properties; }
 
 	EditorExportPreset();
@@ -153,12 +158,13 @@ private:
 	static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
 
 protected:
-	virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0;
 	bool exists_export_template(String template_file_name, String *err) const;
 	String find_export_template(String template_file_name, String *err = NULL) const;
 	void gen_export_flags(Vector<String> &r_flags, int p_flags);
 
 public:
+	virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0;
+
 	struct ExportOption {
 		PropertyInfo option;
 		Variant default_value;
@@ -175,6 +181,7 @@ public:
 	virtual void get_export_options(List<ExportOption> *r_options) = 0;
 	virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { return true; }
 
+	virtual String get_os_name() const = 0;
 	virtual String get_name() const = 0;
 	virtual Ref<Texture> get_logo() const = 0;
 
@@ -203,6 +210,7 @@ public:
 
 	virtual String get_binary_extension() const = 0;
 	virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0;
+	virtual void get_platform_features(List<String> *r_features) = 0;
 
 	EditorExportPlatform();
 };
@@ -253,6 +261,7 @@ class EditorExportPlatformPC : public EditorExportPlatform {
 
 	Ref<ImageTexture> logo;
 	String name;
+	String os_name;
 	String extension;
 
 	String release_file_32;
@@ -260,6 +269,8 @@ class EditorExportPlatformPC : public EditorExportPlatform {
 	String debug_file_32;
 	String debug_file_64;
 
+	Set<String> extra_features;
+
 	bool use64;
 
 public:
@@ -268,6 +279,7 @@ public:
 	virtual void get_export_options(List<ExportOption> *r_options);
 
 	virtual String get_name() const;
+	virtual String get_os_name() const;
 	virtual Ref<Texture> get_logo() const;
 
 	virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
@@ -276,6 +288,7 @@ public:
 
 	void set_extension(const String &p_extension);
 	void set_name(const String &p_name);
+	void set_os_name(const String &p_name);
 
 	void set_logo(const Ref<Texture> &p_loco);
 
@@ -284,6 +297,9 @@ public:
 	void set_debug_64(const String &p_file);
 	void set_debug_32(const String &p_file);
 
+	void add_platform_feature(const String &p_feature);
+	virtual void get_platform_features(List<String> *r_features);
+
 	EditorExportPlatformPC();
 };
 

+ 5 - 5
editor/editor_file_system.cpp

@@ -32,12 +32,12 @@
 #include "editor_node.h"
 #include "editor_resource_preview.h"
 #include "editor_settings.h"
-#include "global_config.h"
 #include "io/resource_import.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "os/file_access.h"
 #include "os/os.h"
+#include "project_settings.h"
 #include "variant_parser.h"
 
 EditorFileSystem *EditorFileSystem::singleton = NULL;
@@ -179,7 +179,7 @@ void EditorFileSystem::_scan_filesystem() {
 	sources_changed.clear();
 	file_cache.clear();
 
-	String project = GlobalConfig::get_singleton()->get_resource_path();
+	String project = ProjectSettings::get_singleton()->get_resource_path();
 
 	String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2");
 	FileAccess *f = FileAccess::open(fscache, FileAccess::READ);
@@ -1008,7 +1008,7 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector
 	if (!filesystem || scanning)
 		return false;
 
-	String f = GlobalConfig::get_singleton()->localize_path(p_file);
+	String f = ProjectSettings::get_singleton()->localize_path(p_file);
 
 	if (!f.begins_with("res://"))
 		return false;
@@ -1121,7 +1121,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p
 	if (!filesystem || scanning)
 		return NULL;
 
-	String f = GlobalConfig::get_singleton()->localize_path(p_path);
+	String f = ProjectSettings::get_singleton()->localize_path(p_path);
 
 	if (!f.begins_with("res://"))
 		return NULL;
@@ -1335,7 +1335,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
 	f->store_line("[params]");
 	f->store_line("");
 
-	//store options in provided order, to avoid file changing
+	//store options in provided order, to avoid file changing. Order is also important because first match is accepted first.
 
 	for (List<ResourceImporter::ImportOption>::Element *E = opts.front(); E; E = E->next()) {
 

+ 25 - 25
editor/editor_node.cpp

@@ -39,7 +39,6 @@
 #include "editor_help.h"
 #include "editor_settings.h"
 #include "editor_themes.h"
-#include "global_config.h"
 #include "io/config_file.h"
 #include "io/stream_peer_ssl.h"
 #include "io/zip_io.h"
@@ -52,6 +51,7 @@
 #include "os/os.h"
 #include "path_remap.h"
 #include "print_string.h"
+#include "project_settings.h"
 #include "pvrtc_compress.h"
 #include "register_exporters.h"
 #include "scene/resources/packed_scene.h"
@@ -163,7 +163,7 @@ void EditorNode::_update_scene_tabs() {
 
 void EditorNode::_update_title() {
 
-	String appname = GlobalConfig::get_singleton()->get("application/config/name");
+	String appname = ProjectSettings::get_singleton()->get("application/config/name");
 	String title = appname.empty() ? String(VERSION_FULL_NAME) : String(_MKSTR(VERSION_NAME) + String(" - ") + appname);
 	String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
 	if (!edited.empty())
@@ -272,7 +272,7 @@ void EditorNode::_notification(int p_what) {
 		}
 		editor_selection->update();
 
-		scene_root->set_size_override(true, Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height")));
+		scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")));
 
 		ResourceImporterTexture::get_singleton()->update_imports();
 	}
@@ -519,7 +519,7 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St
 		flg|=ResourceSaver::FLAG_RELATIVE_PATHS;
 	*/
 
-	String path = GlobalConfig::get_singleton()->localize_path(p_path);
+	String path = ProjectSettings::get_singleton()->localize_path(p_path);
 	Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
 
 	if (err != OK) {
@@ -870,7 +870,7 @@ void EditorNode::_save_scene_with_preview(String p_file) {
 
 		//save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5
 		String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
-		String cache_base = GlobalConfig::get_singleton()->globalize_path(p_file).md5_text();
+		String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text();
 		cache_base = temp_path.plus_file("resthumb-" + cache_base);
 
 		//does not have it, try to load a cached thumbnail
@@ -950,7 +950,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
 	_save_edited_subresources(scene, processed, flg);
 	editor_data.save_editor_external_data();
 	if (err == OK) {
-		scene->set_filename(GlobalConfig::get_singleton()->localize_path(p_file));
+		scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_file));
 		//EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type());
 		if (idx < 0 || idx == editor_data.get_edited_scene())
 			set_current_version(editor_data.get_undo_redo().get_version());
@@ -1029,7 +1029,7 @@ void EditorNode::_import_action(const String &p_action) {
 		EditorImport::generate_version_hashes(src);
 
 
-		Node *dst = SceneLoader::load(editor_data.get_imported_scene(GlobalConfig::get_singleton()->localize_path(_tmp_import_path)));
+		Node *dst = SceneLoader::load(editor_data.get_imported_scene(ProjectSettings::get_singleton()->localize_path(_tmp_import_path)));
 
 		if (!dst) {
 
@@ -1132,8 +1132,8 @@ void EditorNode::_dialog_action(String p_file) {
 		} break;
 		case SETTINGS_PICK_MAIN_SCENE: {
 
-			GlobalConfig::get_singleton()->set("application/run/main_scene", p_file);
-			GlobalConfig::get_singleton()->save();
+			ProjectSettings::get_singleton()->set("application/run/main_scene", p_file);
+			ProjectSettings::get_singleton()->save();
 			//would be nice to show the project manager opened with the highlighted field..
 			_run(false, ""); // automatically run the project
 		} break;
@@ -1802,7 +1802,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
 	List<String> breakpoints;
 	editor_data.get_editor_breakpoints(&breakpoints);
 
-	args = GlobalConfig::get_singleton()->get("editor/main_run_args");
+	args = ProjectSettings::get_singleton()->get("editor/main_run_args");
 
 	Error error = editor_run.run(run_filename, args, breakpoints);
 
@@ -2269,7 +2269,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
 			}
 
 			instanced_scene->generate_instance_state();
-			instanced_scene->set_filename( GlobalConfig::get_singleton()->localize_path(external_file) );
+			instanced_scene->set_filename( ProjectSettings::get_singleton()->localize_path(external_file) );
 
 			editor_data.get_undo_redo().create_action("Instance Scene");
 			editor_data.get_undo_redo().add_do_method(parent,"add_child",instanced_scene);
@@ -2944,9 +2944,9 @@ void EditorNode::_update_addon_config() {
 	}
 
 	if (enabled_addons.size() == 0) {
-		GlobalConfig::get_singleton()->set("editor_plugins/enabled", Variant());
+		ProjectSettings::get_singleton()->set("editor_plugins/enabled", Variant());
 	} else {
-		GlobalConfig::get_singleton()->set("editor_plugins/enabled", enabled_addons);
+		ProjectSettings::get_singleton()->set("editor_plugins/enabled", enabled_addons);
 	}
 
 	project_settings->queue_save();
@@ -3287,7 +3287,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
 	if (p_clear_errors)
 		load_errors->clear();
 
-	String lpath = GlobalConfig::get_singleton()->localize_path(p_scene);
+	String lpath = ProjectSettings::get_singleton()->localize_path(p_scene);
 
 	if (!lpath.begins_with("res://")) {
 
@@ -3575,7 +3575,7 @@ void EditorNode::animation_editor_make_visible(bool p_visible) {
 #endif
 void EditorNode::_add_to_recent_scenes(const String &p_scene) {
 
-	String base = "_" + GlobalConfig::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
+	String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
 	Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array());
 	String name = p_scene;
 	name = name.replace("res://", "");
@@ -3592,7 +3592,7 @@ void EditorNode::_add_to_recent_scenes(const String &p_scene) {
 
 void EditorNode::_open_recent_scene(int p_idx) {
 
-	String base = "_" + GlobalConfig::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
+	String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
 	Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array());
 
 	ERR_FAIL_INDEX(p_idx, rc.size());
@@ -3635,13 +3635,13 @@ void EditorNode::_save_optimized() {
 
 	}
 
-	project_settings->add_remapped_path(GlobalConfig::get_singleton()->localize_path(get_edited_scene()->get_filename()),GlobalConfig::get_singleton()->localize_path(path),platform);
+	project_settings->add_remapped_path(ProjectSettings::get_singleton()->localize_path(get_edited_scene()->get_filename()),ProjectSettings::get_singleton()->localize_path(path),platform);
 #endif
 }
 
 void EditorNode::_update_recent_scenes() {
 
-	String base = "_" + GlobalConfig::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
+	String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
 	Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array());
 	recent_scenes->clear();
 	for (int i = 0; i < rc.size(); i++) {
@@ -5419,7 +5419,7 @@ EditorNode::EditorNode() {
 	VisualServer::get_singleton()->viewport_set_hide_scenario(scene_root->get_viewport_rid(), true);
 	scene_root->set_disable_input(true);
 	scene_root->set_as_audio_listener_2d(true);
-	//scene_root->set_size_override(true,Size2(GlobalConfig::get_singleton()->get("display/width"),GlobalConfig::get_singleton()->get("display/height")));
+	//scene_root->set_size_override(true,Size2(ProjectSettings::get_singleton()->get("display/width"),ProjectSettings::get_singleton()->get("display/height")));
 
 	//scene_root->set_world_2d( Ref<World2D>( memnew( World2D )) );
 
@@ -5948,7 +5948,7 @@ EditorNode::EditorNode() {
 	settings_config_dialog = memnew(EditorSettingsDialog);
 	gui_base->add_child(settings_config_dialog);
 
-	project_settings = memnew(ProjectSettings(&editor_data));
+	project_settings = memnew(ProjectSettingsEditor(&editor_data));
 	gui_base->add_child(project_settings);
 
 	import_confirmation = memnew(ConfirmationDialog);
@@ -6275,7 +6275,7 @@ EditorNode::EditorNode() {
 	Physics2DServer::get_singleton()->set_active(false); // no physics by default if editor
 	ScriptServer::set_scripting_enabled(false); // no scripting by default if editor
 
-	//GlobalConfig::get_singleton()->set("render/room_cull_enabled",false);
+	//ProjectSettings::get_singleton()->set("render/room_cull_enabled",false);
 
 	reference_resource_mem = true;
 	save_external_resources_mem = true;
@@ -6288,7 +6288,7 @@ EditorNode::EditorNode() {
 		//store project name in ssettings
 		String project_name;
 		//figure it out from path
-		project_name = GlobalConfig::get_singleton()->get_resource_path().replace("\\", "/");
+		project_name = ProjectSettings::get_singleton()->get_resource_path().replace("\\", "/");
 		print_line("path: " + project_name);
 		if (project_name.length() && project_name[project_name.length() - 1] == '/')
 			project_name = project_name.substr(0, project_name.length() - 1);
@@ -6296,7 +6296,7 @@ EditorNode::EditorNode() {
 		project_name = project_name.replace("/", "::");
 
 		if (project_name != "") {
-			EditorSettings::get_singleton()->set("projects/" + project_name, GlobalConfig::get_singleton()->get_resource_path());
+			EditorSettings::get_singleton()->set("projects/" + project_name, ProjectSettings::get_singleton()->get_resource_path());
 			EditorSettings::get_singleton()->raise_order("projects/" + project_name);
 			EditorSettings::get_singleton()->save();
 		}
@@ -6377,8 +6377,8 @@ EditorNode::EditorNode() {
 
 		_initializing_addons = true;
 		Vector<String> addons;
-		if (GlobalConfig::get_singleton()->has("editor_plugins/enabled")) {
-			addons = GlobalConfig::get_singleton()->get("editor_plugins/enabled");
+		if (ProjectSettings::get_singleton()->has("editor_plugins/enabled")) {
+			addons = ProjectSettings::get_singleton()->get("editor_plugins/enabled");
 		}
 
 		for (int i = 0; i < addons.size(); i++) {

+ 2 - 2
editor/editor_node.h

@@ -64,7 +64,7 @@
 #include "editor/editor_log.h"
 #include "editor/editor_run_script.h"
 #include "editor/project_export.h"
-#include "editor/project_settings.h"
+#include "editor/project_settings_editor.h"
 #include "editor/resources_dock.h"
 #include "editor/run_settings_dialog.h"
 #include "editor/scene_tree_dock.h"
@@ -310,7 +310,7 @@ private:
 	//OptimizedPresetsDialog *optimized_presets;
 	EditorSettingsDialog *settings_config_dialog;
 	RunSettingsDialog *run_settings_dialog;
-	ProjectSettings *project_settings;
+	ProjectSettingsEditor *project_settings;
 	EditorFileDialog *file;
 	ExportTemplateManager *export_template_manager;
 	FileDialog *file_templates;

+ 2 - 2
editor/editor_plugin_settings.cpp

@@ -30,7 +30,7 @@
 #include "editor_plugin_settings.h"
 
 #include "editor_node.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/config_file.h"
 #include "os/file_access.h"
 #include "os/main_loop.h"
@@ -82,7 +82,7 @@ void EditorPluginSettings::update_plugins() {
 
 	plugins.sort();
 
-	Vector<String> active_plugins = GlobalConfig::get_singleton()->get("editor_plugins/enabled");
+	Vector<String> active_plugins = ProjectSettings::get_singleton()->get("editor_plugins/enabled");
 
 	for (int i = 0; i < plugins.size(); i++) {
 

+ 2 - 2
editor/editor_resource_preview.cpp

@@ -31,7 +31,7 @@
 
 #include "editor_scale.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "message_queue.h"
@@ -206,7 +206,7 @@ void EditorResourcePreview::_thread() {
 				} else {
 
 					String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
-					String cache_base = GlobalConfig::get_singleton()->globalize_path(item.path).md5_text();
+					String cache_base = ProjectSettings::get_singleton()->globalize_path(item.path).md5_text();
 					cache_base = temp_path.plus_file("resthumb-" + cache_base);
 
 					//does not have it, try to load a cached thumbnail

+ 6 - 6
editor/editor_run.cpp

@@ -30,7 +30,7 @@
 #include "editor_run.h"
 
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 
 EditorRun::Status EditorRun::get_status() const {
 
@@ -40,7 +40,7 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
 
 	List<String> args;
 
-	String resource_path = GlobalConfig::get_singleton()->get_resource_path();
+	String resource_path = ProjectSettings::get_singleton()->get_resource_path();
 	String remote_host = EditorSettings::get_singleton()->get("network/debug/remote_host");
 	int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
 
@@ -79,12 +79,12 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
 
 	Size2 desired_size;
 
-	desired_size.x = GlobalConfig::get_singleton()->get("display/window/size/width");
-	desired_size.y = GlobalConfig::get_singleton()->get("display/window/size/height");
+	desired_size.x = ProjectSettings::get_singleton()->get("display/window/size/width");
+	desired_size.y = ProjectSettings::get_singleton()->get("display/window/size/height");
 
 	Size2 test_size;
-	test_size.x = GlobalConfig::get_singleton()->get("display/window/size/test_width");
-	test_size.y = GlobalConfig::get_singleton()->get("display/window/size/test_height");
+	test_size.x = ProjectSettings::get_singleton()->get("display/window/size/test_width");
+	test_size.y = ProjectSettings::get_singleton()->get("display/window/size/test_height");
 	if (test_size.x > 0 && test_size.y > 0) {
 
 		desired_size = test_size;

+ 2 - 2
editor/editor_settings.cpp

@@ -30,7 +30,7 @@
 #include "editor_settings.h"
 
 #include "editor_node.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/compression.h"
 #include "io/config_file.h"
 #include "io/file_access_memory.h"
@@ -329,7 +329,7 @@ void EditorSettings::create() {
 
 		dir->change_dir("config");
 
-		String pcp = GlobalConfig::get_singleton()->get_resource_path();
+		String pcp = ProjectSettings::get_singleton()->get_resource_path();
 		if (pcp.ends_with("/"))
 			pcp = config_path.substr(0, pcp.size() - 1);
 		pcp = pcp.get_file() + "-" + pcp.md5_text();

+ 3 - 3
editor/file_type_cache.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "file_type_cache.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/file_access.h"
 
 FileTypeCache *FileTypeCache::singleton = NULL;
@@ -55,7 +55,7 @@ void FileTypeCache::set_file_type(const String &p_path, const String &p_type) {
 void FileTypeCache::load() {
 
 	GLOBAL_LOCK_FUNCTION
-	String project = GlobalConfig::get_singleton()->get_resource_path();
+	String project = ProjectSettings::get_singleton()->get_resource_path();
 	FileAccess *f = FileAccess::open(project + "/file_type_cache.cch", FileAccess::READ);
 
 	if (!f) {
@@ -80,7 +80,7 @@ void FileTypeCache::load() {
 void FileTypeCache::save() {
 
 	GLOBAL_LOCK_FUNCTION
-	String project = GlobalConfig::get_singleton()->get_resource_path();
+	String project = ProjectSettings::get_singleton()->get_resource_path();
 	FileAccess *f = FileAccess::open(project + "/file_type_cache.cch", FileAccess::WRITE);
 	if (!f) {
 

+ 3 - 3
editor/filesystem_dock.cpp

@@ -31,7 +31,7 @@
 
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "os/dir_access.h"
 #include "os/file_access.h"
@@ -879,7 +879,7 @@ void FileSystemDock::_file_option(int p_option) {
 
 			String path = files->get_item_metadata(idx);
 			if (p_option == FILE_SHOW_IN_EXPLORER) {
-				String dir = GlobalConfig::get_singleton()->globalize_path(path);
+				String dir = ProjectSettings::get_singleton()->globalize_path(path);
 				dir = dir.substr(0, dir.find_last("/"));
 				OS::get_singleton()->shell_open(String("file://") + dir);
 				return;
@@ -1067,7 +1067,7 @@ void FileSystemDock::_folder_option(int p_option) {
 			break;
 		case FOLDER_SHOW_IN_EXPLORER:
 			String path = item->get_metadata(tree->get_selected_column());
-			String dir = GlobalConfig::get_singleton()->globalize_path(path);
+			String dir = ProjectSettings::get_singleton()->globalize_path(path);
 			OS::get_singleton()->shell_open(String("file://") + dir);
 			return;
 	}

+ 9 - 9
editor/import/resource_importer_texture.cpp

@@ -416,26 +416,26 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
 	bool force_normal = normal == 1;
 
 	if (compress_mode == COMPRESS_VIDEO_RAM) {
-		//must import in all formats
+		//must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
 		//Android, GLES 2.x
-		if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
+		if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
 
 			_save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
 			r_platform_variants->push_back("s3tc");
 		}
 
-		if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_etc")) {
-			_save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
-			r_platform_variants->push_back("etc");
-		}
-
-		if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_etc2")) {
+		if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
 
 			_save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
 			r_platform_variants->push_back("etc2");
 		}
 
-		if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
+		if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
+			_save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
+			r_platform_variants->push_back("etc");
+		}
+
+		if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
 
 			_save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
 			r_platform_variants->push_back("pvrtc");

+ 2 - 2
editor/io_plugins/editor_export_scene.cpp

@@ -30,7 +30,7 @@
 #include "editor_export_scene.h"
 #if 0
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "os/dir_access.h"
@@ -63,7 +63,7 @@ Vector<uint8_t> EditorSceneExportPlugin::custom_export(String& p_path,const Ref<
 
 	uint64_t sd=0;
 	String smd5;
-	String gp = GlobalConfig::get_singleton()->globalize_path(p_path);
+	String gp = ProjectSettings::get_singleton()->globalize_path(p_path);
 	String md5=gp.md5_text();
 	String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/");
 

+ 6 - 6
editor/io_plugins/editor_scene_import_plugin.cpp

@@ -31,7 +31,7 @@
 #if 0
 #include "editor/create_dialog.h"
 #include "editor/editor_node.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_saver.h"
 #include "os/file_access.h"
 #include "os/os.h"
@@ -672,9 +672,9 @@ void EditorSceneImportDialog::_choose_save_file(const String& p_path) {
 
 void EditorSceneImportDialog::_choose_script(const String& p_path) {
 
-	String p = GlobalConfig::get_singleton()->localize_path(p_path);
+	String p = ProjectSettings::get_singleton()->localize_path(p_path);
 	if (!p.is_resource_file())
-		p=GlobalConfig::get_singleton()->get_resource_path().path_to(p_path.get_base_dir())+p_path.get_file();
+		p=ProjectSettings::get_singleton()->get_resource_path().path_to(p_path.get_base_dir())+p_path.get_file();
 	script_path->set_text(p);
 
 }
@@ -727,7 +727,7 @@ void EditorSceneImportDialog::_import(bool p_and_open) {
 	if (texture_action->get_selected()==0)
 		dst_path=save_path->get_text();//.get_base_dir();
 	else
-		dst_path=GlobalConfig::get_singleton()->get("import/shared_textures");
+		dst_path=ProjectSettings::get_singleton()->get("import/shared_textures");
 
 	uint32_t flags=0;
 
@@ -1277,7 +1277,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
 	set_hide_on_ok(false);
 
 	GLOBAL_DEF("import/shared_textures","res://");
-	GlobalConfig::get_singleton()->set_custom_property_info("import/shared_textures",PropertyInfo(Variant::STRING,"import/shared_textures",PROPERTY_HINT_DIR));
+	ProjectSettings::get_singleton()->set_custom_property_info("import/shared_textures",PropertyInfo(Variant::STRING,"import/shared_textures",PROPERTY_HINT_DIR));
 
 	import_hb->add_constant_override("separation",30);
 
@@ -2812,7 +2812,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
 
 		String path = texture->get_path();
 		String fname= path.get_file();
-		String target_path = GlobalConfig::get_singleton()->localize_path(target_res_path.plus_file(fname));
+		String target_path = ProjectSettings::get_singleton()->localize_path(target_res_path.plus_file(fname));
 		progress.step(TTR("Import Image:")+" "+fname,3+(idx)*100/imagemap.size());
 
 		idx++;

+ 2 - 2
editor/io_plugins/editor_texture_import_plugin.cpp

@@ -33,7 +33,7 @@
 #include "editor/editor_node.h"
 #include "editor/editor_settings.h"
 #include "editor_atlas.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/image_loader.h"
 #include "io/marshalls.h"
 #include "io/resource_saver.h"
@@ -1653,7 +1653,7 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
 	uint8_t f4[4];
 	encode_uint32(flags,&f4[0]);
 	MD5Init(&ctx);
-	String gp = GlobalConfig::get_singleton()->globalize_path(p_path);
+	String gp = ProjectSettings::get_singleton()->globalize_path(p_path);
 	CharString cs = gp.utf8();
 	MD5Update(&ctx,(unsigned char*)cs.get_data(),cs.length());
 	MD5Update(&ctx,f4,4);

+ 2 - 2
editor/plugins/animation_player_editor_plugin.cpp

@@ -31,7 +31,7 @@
 
 #include "editor/animation_editor.h"
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "os/keyboard.h"
@@ -372,7 +372,7 @@ void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resou
 		flg |= ResourceSaver::FLAG_RELATIVE_PATHS;
 	*/
 
-	String path = GlobalConfig::get_singleton()->localize_path(p_path);
+	String path = ProjectSettings::get_singleton()->localize_path(p_path);
 	Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
 
 	if (err != OK) {

+ 2 - 2
editor/plugins/animation_tree_editor_plugin.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "animation_tree_editor_plugin.h"
 
-#include "core/global_config.h"
+#include "core/project_settings.h"
 #include "core/io/resource_loader.h"
 #include "os/input.h"
 #include "os/keyboard.h"
@@ -1408,7 +1408,7 @@ AnimationTreeEditor::AnimationTreeEditor() {
 
 	file_dialog = memnew(EditorFileDialog);
 	file_dialog->set_enable_multiple_selection(true);
-	file_dialog->set_current_dir(GlobalConfig::get_singleton()->get_resource_path());
+	file_dialog->set_current_dir(ProjectSettings::get_singleton()->get_resource_path());
 	add_child(file_dialog);
 	file_dialog->connect("file_selected", this, "_file_dialog_selected");
 

+ 4 - 4
editor/plugins/canvas_item_editor_plugin.cpp

@@ -35,7 +35,7 @@
 #include "editor/plugins/animation_player_editor_plugin.h"
 #include "editor/plugins/script_editor_plugin.h"
 #include "editor/script_editor_debugger.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/input.h"
 #include "os/keyboard.h"
 #include "print_string.h"
@@ -2007,7 +2007,7 @@ void CanvasItemEditor::_viewport_draw() {
 		VisualServer::get_singleton()->canvas_item_add_line(ci, transform.xform(display_rotate_from), transform.xform(display_rotate_to), rotate_color);
 	}
 
-	Size2 screen_size = Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height"));
+	Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
 
 	Vector2 screen_endpoints[4] = {
 		transform.xform(Vector2(0, 0)),
@@ -2323,7 +2323,7 @@ void CanvasItemEditor::_update_scrollbars() {
 	h_scroll->set_begin(Point2(0, size.height - hmin.height));
 	h_scroll->set_end(Point2(size.width - vmin.width, size.height));
 
-	Size2 screen_rect = Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height"));
+	Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
 
 	Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height));
 
@@ -3697,7 +3697,7 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
 		}
 	}
 
-	instanced_scene->set_filename(GlobalConfig::get_singleton()->localize_path(path));
+	instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path));
 
 	editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene);
 	editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", editor->get_edited_scene());

+ 1 - 1
editor/plugins/editor_preview_plugins.cpp

@@ -186,7 +186,7 @@ Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) {
 Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) {
 
 	String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
-	String cache_base = GlobalConfig::get_singleton()->globalize_path(p_path).md5_text();
+	String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text();
 	cache_base = temp_path.plus_file("resthumb-" + cache_base);
 
 	//does not have it, try to load a cached thumbnail

+ 1 - 1
editor/plugins/resource_preloader_editor_plugin.cpp

@@ -30,7 +30,7 @@
 #include "resource_preloader_editor_plugin.h"
 
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 
 void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {

+ 1 - 1
editor/plugins/sample_editor_plugin.cpp

@@ -31,7 +31,7 @@
 
 #if 0
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 
 

+ 1 - 1
editor/plugins/sample_library_editor_plugin.cpp

@@ -32,7 +32,7 @@
 #include "sample_library_editor_plugin.h"
 
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "sample_editor_plugin.h"
 #include "scene/main/viewport.h"

+ 3 - 3
editor/plugins/script_editor_plugin.cpp

@@ -32,7 +32,7 @@
 #include "editor/editor_node.h"
 #include "editor/editor_settings.h"
 #include "editor/script_editor_debugger.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "os/file_access.h"
@@ -1603,8 +1603,8 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
 		String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags");
 
 		Dictionary keys;
-		keys["project"] = GlobalConfig::get_singleton()->get_resource_path();
-		keys["file"] = GlobalConfig::get_singleton()->globalize_path(p_script->get_path());
+		keys["project"] = ProjectSettings::get_singleton()->get_resource_path();
+		keys["file"] = ProjectSettings::get_singleton()->globalize_path(p_script->get_path());
 		keys["line"] = p_line >= 0 ? p_line : 0;
 		keys["col"] = p_col;
 

+ 9 - 9
editor/plugins/spatial_editor_plugin.cpp

@@ -36,7 +36,7 @@
 #include "editor/editor_settings.h"
 #include "editor/plugins/animation_player_editor_plugin.h"
 #include "editor/spatial_editor_gizmos.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/keyboard.h"
 #include "print_string.h"
 #include "scene/3d/camera.h"
@@ -1717,11 +1717,11 @@ void SpatialEditorViewport::_notification(int p_what) {
 
 		//update shadow atlas if changed
 
-		int shadowmap_size = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/size");
-		int atlas_q0 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
-		int atlas_q1 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
-		int atlas_q2 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
-		int atlas_q3 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
+		int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size");
+		int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
+		int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
+		int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
+		int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
 
 		viewport->set_shadow_atlas_size(shadowmap_size);
 		viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
@@ -1731,10 +1731,10 @@ void SpatialEditorViewport::_notification(int p_what) {
 
 		//update msaa if changed
 
-		int msaa_mode = GlobalConfig::get_singleton()->get("rendering/quality/filters/msaa");
+		int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/filters/msaa");
 		viewport->set_msaa(Viewport::MSAA(msaa_mode));
 
-		bool hdr = GlobalConfig::get_singleton()->get("rendering/quality/depth/hdr");
+		bool hdr = ProjectSettings::get_singleton()->get("rendering/quality/depth/hdr");
 		viewport->set_hdr(hdr);
 
 		bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
@@ -1834,7 +1834,7 @@ void SpatialEditorViewport::_draw() {
 
 	if (previewing) {
 
-		Size2 ss = Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height"));
+		Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
 		float aspect = ss.aspect();
 		Size2 s = get_size();
 

+ 1 - 1
editor/plugins/sprite_frames_editor_plugin.cpp

@@ -30,7 +30,7 @@
 #include "sprite_frames_editor_plugin.h"
 
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "scene/3d/sprite_3d.h"
 

+ 1 - 1
editor/plugins/texture_editor_plugin.cpp

@@ -30,7 +30,7 @@
 #include "texture_editor_plugin.h"
 
 #include "editor/editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 
 void TextureEditor::_gui_input(Ref<InputEvent> p_event) {

+ 74 - 3
editor/project_export.cpp

@@ -32,7 +32,7 @@
 #include "editor_data.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/image_loader.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
@@ -51,6 +51,7 @@ void ProjectExportDialog::_notification(int p_what) {
 		case NOTIFICATION_READY: {
 			delete_preset->set_icon(get_icon("Del", "EditorIcons"));
 			connect("confirmed", this, "_export_pck_zip");
+			custom_feature_display->get_parent_control()->add_style_override("panel", get_stylebox("bg", "Tree"));
 		} break;
 		case NOTIFICATION_POPUP_HIDE: {
 			EditorSettings::get_singleton()->set("interface/dialogs/export_bounds", get_rect());
@@ -240,9 +241,62 @@ void ProjectExportDialog::_edit_preset(int p_index) {
 		export_button->set_disabled(false);
 	}
 
+	custom_features->set_text(current->get_custom_features());
+	_update_feature_list();
+
 	updating = false;
 }
 
+void ProjectExportDialog::_update_feature_list() {
+
+	Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
+	ERR_FAIL_COND(current.is_null());
+
+	Set<String> fset;
+	List<String> features;
+
+	current->get_platform()->get_platform_features(&features);
+	current->get_platform()->get_preset_features(current, &features);
+
+	String custom = current->get_custom_features();
+	Vector<String> custom_list = custom.split(",");
+	for (int i = 0; i < custom_list.size(); i++) {
+		String f = custom_list[i].strip_edges();
+		if (f != String()) {
+			features.push_back(f);
+		}
+	}
+
+	for (List<String>::Element *E = features.front(); E; E = E->next()) {
+		fset.insert(E->get());
+	}
+
+	custom_feature_display->clear();
+	for (Set<String>::Element *E = fset.front(); E; E = E->next()) {
+		String f = E->get();
+		if (E->next()) {
+			f += ", ";
+		}
+		custom_feature_display->add_text(f);
+	}
+}
+
+void ProjectExportDialog::_custom_features_changed(const String &p_text) {
+
+	if (updating)
+		return;
+
+	Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
+	ERR_FAIL_COND(current.is_null());
+
+	current->set_custom_features(p_text);
+	_update_feature_list();
+}
+
+void ProjectExportDialog::_tab_changed(int) {
+	_update_feature_list();
+}
+
 void ProjectExportDialog::_patch_button_pressed(Object *p_item, int p_column, int p_id) {
 
 	TreeItem *ti = (TreeItem *)p_item;
@@ -294,10 +348,10 @@ void ProjectExportDialog::_patch_selected(const String &p_path) {
 
 	if (patch_index >= patches.size()) {
 
-		current->add_patch(GlobalConfig::get_singleton()->get_resource_path().path_to(p_path) + "*");
+		current->add_patch(ProjectSettings::get_singleton()->get_resource_path().path_to(p_path) + "*");
 	} else {
 		String enabled = patches[patch_index].ends_with("*") ? String("*") : String();
-		current->set_patch(patch_index, GlobalConfig::get_singleton()->get_resource_path().path_to(p_path) + enabled);
+		current->set_patch(patch_index, ProjectSettings::get_singleton()->get_resource_path().path_to(p_path) + enabled);
 	}
 
 	_edit_preset(presets->get_current());
@@ -705,6 +759,8 @@ void ProjectExportDialog::_bind_methods() {
 	ClassDB::bind_method("_open_export_template_manager", &ProjectExportDialog::_open_export_template_manager);
 	ClassDB::bind_method("_export_project", &ProjectExportDialog::_export_project);
 	ClassDB::bind_method("_export_project_to_path", &ProjectExportDialog::_export_project_to_path);
+	ClassDB::bind_method("_custom_features_changed", &ProjectExportDialog::_custom_features_changed);
+	ClassDB::bind_method("_tab_changed", &ProjectExportDialog::_tab_changed);
 }
 ProjectExportDialog::ProjectExportDialog() {
 
@@ -828,6 +884,21 @@ ProjectExportDialog::ProjectExportDialog() {
 	patch_erase->connect("confirmed", this, "_patch_deleted");
 	add_child(patch_erase);
 
+	VBoxContainer *feature_vb = memnew(VBoxContainer);
+	feature_vb->set_name(TTR("Features"));
+	custom_features = memnew(LineEdit);
+	custom_features->connect("text_changed", this, "_custom_features_changed");
+	feature_vb->add_margin_child(TTR("Custom (comma-separated):"), custom_features);
+	Panel *features_panel = memnew(Panel);
+	custom_feature_display = memnew(RichTextLabel);
+	features_panel->add_child(custom_feature_display);
+	custom_feature_display->set_area_as_parent_rect(10 * EDSCALE);
+	custom_feature_display->set_v_size_flags(SIZE_EXPAND_FILL);
+	feature_vb->add_margin_child(TTR("Feature List:"), features_panel, true);
+	sections->add_child(feature_vb);
+
+	sections->connect("tab_changed", this, "_tab_changed");
+
 	//disable by default
 	name->set_editable(false);
 	runnable->set_disabled(true);

+ 9 - 0
editor/project_export.h

@@ -40,6 +40,7 @@
 #include "scene/gui/label.h"
 #include "scene/gui/link_button.h"
 #include "scene/gui/option_button.h"
+#include "scene/gui/rich_text_label.h"
 #include "scene/gui/tab_container.h"
 #include "scene/gui/tree.h"
 #include "scene/main/timer.h"
@@ -91,6 +92,9 @@ private:
 
 	Button *export_button;
 
+	LineEdit *custom_features;
+	RichTextLabel *custom_feature_display;
+
 	Label *export_error;
 	HBoxContainer *export_templates_error;
 
@@ -132,6 +136,11 @@ private:
 	void _export_project();
 	void _export_project_to_path(const String &p_path);
 
+	void _update_feature_list();
+	void _custom_features_changed(const String &p_text);
+
+	void _tab_changed(int);
+
 protected:
 	void _notification(int p_what);
 	static void _bind_methods();

+ 259 - 191
editor/project_settings.cpp → editor/project_settings_editor.cpp

@@ -27,17 +27,17 @@
 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
-#include "project_settings.h"
+#include "project_settings_editor.h"
 
 #include "editor_node.h"
-#include "global_config.h"
 #include "global_constants.h"
 #include "os/keyboard.h"
+#include "project_settings.h"
 #include "scene/gui/margin_container.h"
 #include "scene/gui/tab_container.h"
 #include "translation.h"
 
-ProjectSettings *ProjectSettings::singleton = NULL;
+ProjectSettingsEditor *ProjectSettingsEditor::singleton = NULL;
 
 static const char *_button_names[JOY_BUTTON_MAX] = {
 	"PS Cross, XBox A, Nintendo B",
@@ -72,11 +72,11 @@ static const char *_axis_names[JOY_AXIS_MAX * 2] = {
 	"", " (R2)"
 };
 
-void ProjectSettings::_notification(int p_what) {
+void ProjectSettingsEditor::_notification(int p_what) {
 
 	switch (p_what) {
 		case NOTIFICATION_ENTER_TREE: {
-			globals_editor->edit(GlobalConfig::get_singleton());
+			globals_editor->edit(ProjectSettings::get_singleton());
 
 			search_button->set_icon(get_icon("Search", "EditorIcons"));
 			clear_button->set_icon(get_icon("Close", "EditorIcons"));
@@ -112,7 +112,7 @@ void ProjectSettings::_notification(int p_what) {
 	}
 }
 
-void ProjectSettings::_action_selected() {
+void ProjectSettingsEditor::_action_selected() {
 
 	TreeItem *ti = input_editor->get_selected();
 	if (!ti || !ti->is_editable(0))
@@ -122,7 +122,7 @@ void ProjectSettings::_action_selected() {
 	edit_idx = -1;
 }
 
-void ProjectSettings::_action_edited() {
+void ProjectSettingsEditor::_action_edited() {
 
 	TreeItem *ti = input_editor->get_selected();
 	if (!ti)
@@ -146,7 +146,7 @@ void ProjectSettings::_action_edited() {
 
 	String action_prop = "input/" + new_name;
 
-	if (GlobalConfig::get_singleton()->has(action_prop)) {
+	if (ProjectSettings::get_singleton()->has(action_prop)) {
 
 		ti->set_text(0, old_name);
 		add_at = "input/" + old_name;
@@ -156,17 +156,17 @@ void ProjectSettings::_action_edited() {
 		return;
 	}
 
-	int order = GlobalConfig::get_singleton()->get_order(add_at);
-	Array va = GlobalConfig::get_singleton()->get(add_at);
+	int order = ProjectSettings::get_singleton()->get_order(add_at);
+	Array va = ProjectSettings::get_singleton()->get(add_at);
 
 	setting = true;
 	undo_redo->create_action(TTR("Rename Input Action Event"));
-	undo_redo->add_do_method(GlobalConfig::get_singleton(), "clear", add_at);
-	undo_redo->add_do_method(GlobalConfig::get_singleton(), "set", action_prop, va);
-	undo_redo->add_do_method(GlobalConfig::get_singleton(), "set_order", action_prop, order);
-	undo_redo->add_undo_method(GlobalConfig::get_singleton(), "clear", action_prop);
-	undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set", add_at, va);
-	undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", add_at, order);
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", add_at);
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_prop, va);
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", action_prop, order);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", action_prop);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", add_at, va);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", add_at, order);
 	undo_redo->add_do_method(this, "_update_actions");
 	undo_redo->add_undo_method(this, "_update_actions");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -177,12 +177,12 @@ void ProjectSettings::_action_edited() {
 	add_at = action_prop;
 }
 
-void ProjectSettings::_device_input_add() {
+void ProjectSettingsEditor::_device_input_add() {
 
 	Ref<InputEvent> ie;
 	String name = add_at;
 	int idx = edit_idx;
-	Variant old_val = GlobalConfig::get_singleton()->get(name);
+	Variant old_val = ProjectSettings::get_singleton()->get(name);
 	Array arr = old_val;
 	//	ie.device = device_id->get_value();
 	//	ie.type = add_type;
@@ -260,8 +260,8 @@ void ProjectSettings::_device_input_add() {
 	}
 
 	undo_redo->create_action(TTR("Add Input Action Event"));
-	undo_redo->add_do_method(GlobalConfig::get_singleton(), "set", name, arr);
-	undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set", name, old_val);
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, arr);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
 	undo_redo->add_do_method(this, "_update_actions");
 	undo_redo->add_undo_method(this, "_update_actions");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -271,7 +271,7 @@ void ProjectSettings::_device_input_add() {
 	_show_last_added(ie, name);
 }
 
-void ProjectSettings::_press_a_key_confirm() {
+void ProjectSettingsEditor::_press_a_key_confirm() {
 
 	if (last_wait_for_key.is_null())
 		return;
@@ -287,7 +287,7 @@ void ProjectSettings::_press_a_key_confirm() {
 	String name = add_at;
 	int idx = edit_idx;
 
-	Variant old_val = GlobalConfig::get_singleton()->get(name);
+	Variant old_val = ProjectSettings::get_singleton()->get(name);
 	Array arr = old_val;
 
 	for (int i = 0; i < arr.size(); i++) {
@@ -307,8 +307,8 @@ void ProjectSettings::_press_a_key_confirm() {
 	}
 
 	undo_redo->create_action(TTR("Add Input Action Event"));
-	undo_redo->add_do_method(GlobalConfig::get_singleton(), "set", name, arr);
-	undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set", name, old_val);
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, arr);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
 	undo_redo->add_do_method(this, "_update_actions");
 	undo_redo->add_undo_method(this, "_update_actions");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -318,7 +318,7 @@ void ProjectSettings::_press_a_key_confirm() {
 	_show_last_added(ie, name);
 }
 
-void ProjectSettings::_show_last_added(const Ref<InputEvent> &p_event, const String &p_name) {
+void ProjectSettingsEditor::_show_last_added(const Ref<InputEvent> &p_event, const String &p_name) {
 	TreeItem *r = input_editor->get_root();
 
 	String name = p_name;
@@ -351,7 +351,7 @@ void ProjectSettings::_show_last_added(const Ref<InputEvent> &p_event, const Str
 	if (found) input_editor->ensure_cursor_is_visible();
 }
 
-void ProjectSettings::_wait_for_key(const Ref<InputEvent> &p_event) {
+void ProjectSettingsEditor::_wait_for_key(const Ref<InputEvent> &p_event) {
 
 	Ref<InputEventKey> k = p_event;
 
@@ -373,7 +373,7 @@ void ProjectSettings::_wait_for_key(const Ref<InputEvent> &p_event) {
 	}
 }
 
-void ProjectSettings::_add_item(int p_item, Ref<InputEvent> p_exiting_event) {
+void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) {
 
 	add_type = InputType(p_item);
 
@@ -458,7 +458,7 @@ void ProjectSettings::_add_item(int p_item, Ref<InputEvent> p_exiting_event) {
 	}
 }
 
-void ProjectSettings::_edit_item(Ref<InputEvent> p_exiting_event) {
+void ProjectSettingsEditor::_edit_item(Ref<InputEvent> p_exiting_event) {
 
 	InputType ie_type;
 
@@ -480,7 +480,7 @@ void ProjectSettings::_edit_item(Ref<InputEvent> p_exiting_event) {
 
 	_add_item(ie_type, p_exiting_event);
 }
-void ProjectSettings::_action_activated() {
+void ProjectSettingsEditor::_action_activated() {
 
 	TreeItem *ti = input_editor->get_selected();
 
@@ -489,7 +489,7 @@ void ProjectSettings::_action_activated() {
 
 	String name = "input/" + ti->get_parent()->get_text(0);
 	int idx = ti->get_metadata(0);
-	Array va = GlobalConfig::get_singleton()->get(name);
+	Array va = ProjectSettings::get_singleton()->get(name);
 
 	ERR_FAIL_INDEX(idx, va.size());
 
@@ -503,7 +503,7 @@ void ProjectSettings::_action_activated() {
 	_edit_item(ie);
 }
 
-void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_id) {
+void ProjectSettingsEditor::_action_button_pressed(Object *p_obj, int p_column, int p_id) {
 
 	TreeItem *ti = p_obj->cast_to<TreeItem>();
 
@@ -528,13 +528,13 @@ void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_
 			//remove main thing
 
 			String name = "input/" + ti->get_text(0);
-			Variant old_val = GlobalConfig::get_singleton()->get(name);
-			int order = GlobalConfig::get_singleton()->get_order(name);
+			Variant old_val = ProjectSettings::get_singleton()->get(name);
+			int order = ProjectSettings::get_singleton()->get_order(name);
 
 			undo_redo->create_action(TTR("Add Input Action"));
-			undo_redo->add_do_method(GlobalConfig::get_singleton(), "clear", name);
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set", name, old_val);
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set_order", name, order);
+			undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", name);
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", name, order);
 			undo_redo->add_do_method(this, "_update_actions");
 			undo_redo->add_undo_method(this, "_update_actions");
 			undo_redo->add_do_method(this, "_settings_changed");
@@ -544,7 +544,7 @@ void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_
 		} else {
 			//remove action
 			String name = "input/" + ti->get_parent()->get_text(0);
-			Variant old_val = GlobalConfig::get_singleton()->get(name);
+			Variant old_val = ProjectSettings::get_singleton()->get(name);
 			int idx = ti->get_metadata(0);
 
 			Array va = old_val;
@@ -559,8 +559,8 @@ void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_
 			va.resize(va.size() - 1);
 
 			undo_redo->create_action(TTR("Erase Input Action Event"));
-			undo_redo->add_do_method(GlobalConfig::get_singleton(), "set", name, va);
-			undo_redo->add_undo_method(GlobalConfig::get_singleton(), "set", name, old_val);
+			undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, va);
+			undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
 			undo_redo->add_do_method(this, "_update_actions");
 			undo_redo->add_undo_method(this, "_update_actions");
 			undo_redo->add_do_method(this, "_settings_changed");
@@ -579,7 +579,7 @@ void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_
 			//edit action
 			String name = "input/" + ti->get_parent()->get_text(0);
 			int idx = ti->get_metadata(0);
-			Array va = GlobalConfig::get_singleton()->get(name);
+			Array va = ProjectSettings::get_singleton()->get(name);
 
 			ERR_FAIL_INDEX(idx, va.size());
 
@@ -596,7 +596,7 @@ void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_
 	}
 }
 
-void ProjectSettings::_update_actions() {
+void ProjectSettingsEditor::_update_actions() {
 
 	if (setting)
 		return;
@@ -606,7 +606,7 @@ void ProjectSettings::_update_actions() {
 	input_editor->set_hide_root(true);
 
 	List<PropertyInfo> props;
-	GlobalConfig::get_singleton()->get_property_list(&props);
+	ProjectSettings::get_singleton()->get_property_list(&props);
 
 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
@@ -622,14 +622,14 @@ void ProjectSettings::_update_actions() {
 		//item->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
 		item->set_text(0, name);
 		item->add_button(0, get_icon("Add", "EditorIcons"), 1, false, TTR("Add Event"));
-		if (!GlobalConfig::get_singleton()->get_input_presets().find(pi.name)) {
+		if (!ProjectSettings::get_singleton()->get_input_presets().find(pi.name)) {
 			item->add_button(0, get_icon("Remove", "EditorIcons"), 2, false, TTR("Remove"));
 			item->set_editable(0, true);
 		}
 		item->set_custom_bg_color(0, get_color("prop_subsection", "Editor"));
 		//item->set_checked(0,pi.usage&PROPERTY_USAGE_CHECKED);
 
-		Array actions = GlobalConfig::get_singleton()->get(pi.name);
+		Array actions = ProjectSettings::get_singleton()->get(pi.name);
 
 		for (int i = 0; i < actions.size(); i++) {
 
@@ -706,7 +706,7 @@ void ProjectSettings::_update_actions() {
 	}
 }
 
-void ProjectSettings::popup_project_settings() {
+void ProjectSettingsEditor::popup_project_settings() {
 
 	// Restore valid window bounds or pop up at default size.
 	if (EditorSettings::get_singleton()->has("interface/dialogs/project_settings_bounds")) {
@@ -720,7 +720,7 @@ void ProjectSettings::popup_project_settings() {
 	plugin_settings->update_plugins();
 }
 
-void ProjectSettings::_item_selected() {
+void ProjectSettingsEditor::_item_selected() {
 
 	TreeItem *ti = globals_editor->get_property_editor()->get_scene_tree()->get_selected();
 	if (!ti)
@@ -729,15 +729,15 @@ void ProjectSettings::_item_selected() {
 		return;
 	category->set_text(globals_editor->get_current_section());
 	property->set_text(ti->get_text(0));
-	popup_platform->set_disabled(false);
+	popup_copy_to_feature->set_disabled(false);
 }
 
-void ProjectSettings::_item_adds(String) {
+void ProjectSettingsEditor::_item_adds(String) {
 
 	_item_add();
 }
 
-void ProjectSettings::_item_add() {
+void ProjectSettingsEditor::_item_add() {
 
 	Variant value;
 	switch (type->get_selected()) {
@@ -765,12 +765,12 @@ void ProjectSettings::_item_add() {
 
 	undo_redo->create_action("Add Global Property");
 
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), name, value);
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), name, value);
 
-	if (GlobalConfig::get_singleton()->has(name)) {
-		undo_redo->add_undo_property(GlobalConfig::get_singleton(), name, GlobalConfig::get_singleton()->get(name));
+	if (ProjectSettings::get_singleton()->has(name)) {
+		undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, ProjectSettings::get_singleton()->get(name));
 	} else {
-		undo_redo->add_undo_property(GlobalConfig::get_singleton(), name, Variant());
+		undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, Variant());
 	}
 
 	undo_redo->add_do_method(globals_editor, "update_category_list");
@@ -786,20 +786,35 @@ void ProjectSettings::_item_add() {
 	_settings_changed();
 }
 
-void ProjectSettings::_item_del() {
+void ProjectSettingsEditor::_item_del() {
 
-	String catname = category->get_text().strip_edges();
-	//ERR_FAIL_COND(!catname.is_valid_identifier());
-	String propname = property->get_text().strip_edges();
-	//ERR_FAIL_COND(!propname.is_valid_identifier());
+	String path = globals_editor->get_property_editor()->get_selected_path();
+	if (path == String()) {
+		EditorNode::get_singleton()->show_warning(TTR("Select an setting item first!"));
+		return;
+	}
 
-	String name = catname != "" ? catname + "/" + propname : propname;
+	String property = globals_editor->get_current_section().plus_file(path);
 
-	undo_redo->create_action("Delete Global Property");
+	if (!ProjectSettings::get_singleton()->has(property)) {
+		EditorNode::get_singleton()->show_warning(TTR("No property '" + property + "' exists."));
+		return;
+	}
 
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), name, Variant());
+	if (ProjectSettings::get_singleton()->get_order(property) < ProjectSettings::NO_BUILTIN_ORDER_BASE) {
+		EditorNode::get_singleton()->show_warning(TTR("Setting '" + property + "' is internal, and it can't be deleted."));
+		return;
+	}
 
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), name, GlobalConfig::get_singleton()->get(name));
+	print_line("to delete.. " + property);
+	undo_redo->create_action(TTR("Delete Item"));
+
+	Variant value = ProjectSettings::get_singleton()->get(property);
+	int order = ProjectSettings::get_singleton()->get_order(property);
+
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", property);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property, value);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", property, order);
 
 	undo_redo->add_do_method(globals_editor, "update_category_list");
 	undo_redo->add_undo_method(globals_editor, "update_category_list");
@@ -808,16 +823,14 @@ void ProjectSettings::_item_del() {
 	undo_redo->add_undo_method(this, "_settings_changed");
 
 	undo_redo->commit_action();
-
-	_settings_changed();
 }
 
-void ProjectSettings::_action_adds(String) {
+void ProjectSettingsEditor::_action_adds(String) {
 
 	_action_add();
 }
 
-void ProjectSettings::_action_add() {
+void ProjectSettingsEditor::_action_add() {
 
 	String action = action_name->get_text();
 	if (action.find("/") != -1 || action.find(":") != -1 || action == "") {
@@ -826,7 +839,7 @@ void ProjectSettings::_action_add() {
 		return;
 	}
 
-	if (GlobalConfig::get_singleton()->has("input/" + action)) {
+	if (ProjectSettings::get_singleton()->has("input/" + action)) {
 		message->set_text(vformat(TTR("Action '%s' already exists!"), action));
 		message->popup_centered(Size2(300, 100));
 		return;
@@ -835,8 +848,8 @@ void ProjectSettings::_action_add() {
 	Array va;
 	String name = "input/" + action;
 	undo_redo->create_action(TTR("Add Input Action Event"));
-	undo_redo->add_do_method(GlobalConfig::get_singleton(), "set", name, va);
-	undo_redo->add_undo_method(GlobalConfig::get_singleton(), "clear", name);
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, va);
+	undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
 	undo_redo->add_do_method(this, "_update_actions");
 	undo_redo->add_undo_method(this, "_update_actions");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -859,66 +872,119 @@ void ProjectSettings::_action_add() {
 	input_editor->ensure_cursor_is_visible();
 }
 
-void ProjectSettings::_item_checked(const String &p_item, bool p_check) {
+void ProjectSettingsEditor::_item_checked(const String &p_item, bool p_check) {
 }
 
-void ProjectSettings::_save() {
+void ProjectSettingsEditor::_save() {
 
-	Error err = GlobalConfig::get_singleton()->save();
+	Error err = ProjectSettings::get_singleton()->save();
 	message->set_text(err != OK ? TTR("Error saving settings.") : TTR("Settings saved OK."));
 	message->popup_centered(Size2(300, 100));
 }
 
-void ProjectSettings::_settings_prop_edited(const String &p_name) {
+void ProjectSettingsEditor::_settings_prop_edited(const String &p_name) {
 
 	String full_item = globals_editor->get_full_item_path(p_name);
 
 	_settings_changed();
 }
 
-void ProjectSettings::_settings_changed() {
+void ProjectSettingsEditor::_settings_changed() {
 
 	timer->start();
 }
 
-void ProjectSettings::queue_save() {
+void ProjectSettingsEditor::queue_save() {
 	_settings_changed();
 }
 
-void ProjectSettings::_copy_to_platform(int p_which) {
+void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
 
-	String catname = category->get_text();
-	if (!catname.is_valid_identifier()) {
-		message->set_text("Invalid Category.\nValid characters: a-z,A-Z,0-9 or _");
-		message->popup_centered(Size2(300, 100));
-		return;
+	Set<String> presets;
+
+	presets.insert("s3tc");
+	presets.insert("etc");
+	presets.insert("etc2");
+	presets.insert("pvrtc");
+	presets.insert("debug");
+	presets.insert("release");
+
+	for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
+		List<String> p;
+		EditorExport::get_singleton()->get_export_platform(i)->get_platform_features(&p);
+		for (List<String>::Element *E = p.front(); E; E = E->next()) {
+			presets.insert(E->get());
+		}
 	}
 
-	String propname = property->get_text();
-	if (!propname.is_valid_identifier()) {
-		message->set_text("Invalid Property.\nValid characters: a-z,A-Z,0-9 or _");
-		message->popup_centered(Size2(300, 100));
+	for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
+
+		List<String> p;
+		EditorExport::get_singleton()->get_export_preset(i)->get_platform()->get_preset_features(EditorExport::get_singleton()->get_export_preset(i), &p);
+		for (List<String>::Element *E = p.front(); E; E = E->next()) {
+			presets.insert(E->get());
+		}
+
+		String custom = EditorExport::get_singleton()->get_export_preset(i)->get_custom_features();
+		Vector<String> custom_list = custom.split(",");
+		for (int i = 0; i < custom_list.size(); i++) {
+			String f = custom_list[i].strip_edges();
+			if (f != String()) {
+				presets.insert(f);
+			}
+		}
+	}
+
+	popup_copy_to_feature->get_popup()->clear();
+	int id = 0;
+	for (Set<String>::Element *E = presets.front(); E; E = E->next()) {
+		popup_copy_to_feature->get_popup()->add_item(E->get(), id++);
+	}
+}
+
+void ProjectSettingsEditor::_copy_to_platform(int p_which) {
+
+	String path = globals_editor->get_property_editor()->get_selected_path();
+	if (path == String()) {
+		EditorNode::get_singleton()->show_warning(TTR("Select an setting item first!"));
 		return;
 	}
 
-	String name = catname + "/" + propname;
-	Variant value = GlobalConfig::get_singleton()->get(name);
+	String property = globals_editor->get_current_section().plus_file(path);
 
-	catname += "." + popup_platform->get_popup()->get_item_text(p_which);
-	name = catname + "/" + propname;
+	undo_redo->create_action(TTR("Override for Feature"));
 
-	GlobalConfig::get_singleton()->set(name, value);
-	globals_editor->get_property_editor()->update_tree();
+	Variant value = ProjectSettings::get_singleton()->get(property);
+	if (property.find(".") != -1) { //overwriting overwrite, keep overwrite
+		undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", property);
+		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property, value);
+	}
+
+	String feature = popup_copy_to_feature->get_popup()->get_item_text(p_which);
+	String new_path = property + "." + feature;
+
+	undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", new_path, value);
+	if (ProjectSettings::get_singleton()->has(new_path)) {
+		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", new_path, ProjectSettings::get_singleton()->get(new_path));
+	}
+
+	undo_redo->add_do_method(globals_editor, "update_category_list");
+	undo_redo->add_undo_method(globals_editor, "update_category_list");
+
+	undo_redo->add_do_method(this, "_settings_changed");
+	undo_redo->add_undo_method(this, "_settings_changed");
+
+	undo_redo->commit_action();
 }
 
-void ProjectSettings::add_translation(const String &p_translation) {
+void ProjectSettingsEditor::add_translation(const String &p_translation) {
 
 	_translation_add(p_translation);
 }
 
-void ProjectSettings::_translation_add(const String &p_path) {
+void ProjectSettingsEditor::_translation_add(const String &p_path) {
 
-	PoolStringArray translations = GlobalConfig::get_singleton()->get("locale/translations");
+	PoolStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
 
 	for (int i = 0; i < translations.size(); i++) {
 
@@ -928,8 +994,8 @@ void ProjectSettings::_translation_add(const String &p_path) {
 
 	translations.push_back(p_path);
 	undo_redo->create_action(TTR("Add Translation"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translations", translations);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translations", GlobalConfig::get_singleton()->get("locale/translations"));
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations", translations);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations", ProjectSettings::get_singleton()->get("locale/translations"));
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -937,27 +1003,27 @@ void ProjectSettings::_translation_add(const String &p_path) {
 	undo_redo->commit_action();
 }
 
-void ProjectSettings::_translation_file_open() {
+void ProjectSettingsEditor::_translation_file_open() {
 
 	translation_file_open->popup_centered_ratio();
 }
 
-void ProjectSettings::_translation_delete(Object *p_item, int p_column, int p_button) {
+void ProjectSettingsEditor::_translation_delete(Object *p_item, int p_column, int p_button) {
 
 	TreeItem *ti = p_item->cast_to<TreeItem>();
 	ERR_FAIL_COND(!ti);
 
 	int idx = ti->get_metadata(0);
 
-	PoolStringArray translations = GlobalConfig::get_singleton()->get("locale/translations");
+	PoolStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
 
 	ERR_FAIL_INDEX(idx, translations.size());
 
 	translations.remove(idx);
 
 	undo_redo->create_action(TTR("Remove Translation"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translations", translations);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translations", GlobalConfig::get_singleton()->get("locale/translations"));
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations", translations);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations", ProjectSettings::get_singleton()->get("locale/translations"));
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -965,18 +1031,18 @@ void ProjectSettings::_translation_delete(Object *p_item, int p_column, int p_bu
 	undo_redo->commit_action();
 }
 
-void ProjectSettings::_translation_res_file_open() {
+void ProjectSettingsEditor::_translation_res_file_open() {
 
 	translation_res_file_open->popup_centered_ratio();
 }
 
-void ProjectSettings::_translation_res_add(const String &p_path) {
+void ProjectSettingsEditor::_translation_res_add(const String &p_path) {
 
 	Variant prev;
 	Dictionary remaps;
 
-	if (GlobalConfig::get_singleton()->has("locale/translation_remaps")) {
-		remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+	if (ProjectSettings::get_singleton()->has("locale/translation_remaps")) {
+		remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 		prev = remaps;
 	}
 
@@ -986,8 +1052,8 @@ void ProjectSettings::_translation_res_add(const String &p_path) {
 	remaps[p_path] = PoolStringArray();
 
 	undo_redo->create_action(TTR("Add Remapped Path"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translation_remaps", remaps);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translation_remaps", prev);
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", prev);
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -995,15 +1061,15 @@ void ProjectSettings::_translation_res_add(const String &p_path) {
 	undo_redo->commit_action();
 }
 
-void ProjectSettings::_translation_res_option_file_open() {
+void ProjectSettingsEditor::_translation_res_option_file_open() {
 
 	translation_res_option_file_open->popup_centered_ratio();
 }
-void ProjectSettings::_translation_res_option_add(const String &p_path) {
+void ProjectSettingsEditor::_translation_res_option_add(const String &p_path) {
 
-	ERR_FAIL_COND(!GlobalConfig::get_singleton()->has("locale/translation_remaps"));
+	ERR_FAIL_COND(!ProjectSettings::get_singleton()->has("locale/translation_remaps"));
 
-	Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+	Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 
 	TreeItem *k = translation_remap->get_selected();
 	ERR_FAIL_COND(!k);
@@ -1016,8 +1082,8 @@ void ProjectSettings::_translation_res_option_add(const String &p_path) {
 	remaps[key] = r;
 
 	undo_redo->create_action(TTR("Resource Remap Add Remap"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translation_remaps", remaps);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translation_remaps", GlobalConfig::get_singleton()->get("locale/translation_remaps"));
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -1025,7 +1091,7 @@ void ProjectSettings::_translation_res_option_add(const String &p_path) {
 	undo_redo->commit_action();
 }
 
-void ProjectSettings::_translation_res_select() {
+void ProjectSettingsEditor::_translation_res_select() {
 
 	if (updating_translations)
 		return;
@@ -1033,15 +1099,15 @@ void ProjectSettings::_translation_res_select() {
 	call_deferred("_update_translations");
 }
 
-void ProjectSettings::_translation_res_option_changed() {
+void ProjectSettingsEditor::_translation_res_option_changed() {
 
 	if (updating_translations)
 		return;
 
-	if (!GlobalConfig::get_singleton()->has("locale/translation_remaps"))
+	if (!ProjectSettings::get_singleton()->has("locale/translation_remaps"))
 		return;
 
-	Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+	Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 
 	TreeItem *k = translation_remap->get_selected();
 	ERR_FAIL_COND(!k);
@@ -1065,8 +1131,8 @@ void ProjectSettings::_translation_res_option_changed() {
 
 	updating_translations = true;
 	undo_redo->create_action(TTR("Change Resource Remap Language"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translation_remaps", remaps);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translation_remaps", GlobalConfig::get_singleton()->get("locale/translation_remaps"));
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -1075,15 +1141,15 @@ void ProjectSettings::_translation_res_option_changed() {
 	updating_translations = false;
 }
 
-void ProjectSettings::_translation_res_delete(Object *p_item, int p_column, int p_button) {
+void ProjectSettingsEditor::_translation_res_delete(Object *p_item, int p_column, int p_button) {
 
 	if (updating_translations)
 		return;
 
-	if (!GlobalConfig::get_singleton()->has("locale/translation_remaps"))
+	if (!ProjectSettings::get_singleton()->has("locale/translation_remaps"))
 		return;
 
-	Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+	Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 
 	TreeItem *k = p_item->cast_to<TreeItem>();
 
@@ -1093,8 +1159,8 @@ void ProjectSettings::_translation_res_delete(Object *p_item, int p_column, int
 	remaps.erase(key);
 
 	undo_redo->create_action(TTR("Remove Resource Remap"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translation_remaps", remaps);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translation_remaps", GlobalConfig::get_singleton()->get("locale/translation_remaps"));
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -1102,15 +1168,15 @@ void ProjectSettings::_translation_res_delete(Object *p_item, int p_column, int
 	undo_redo->commit_action();
 }
 
-void ProjectSettings::_translation_res_option_delete(Object *p_item, int p_column, int p_button) {
+void ProjectSettingsEditor::_translation_res_option_delete(Object *p_item, int p_column, int p_button) {
 
 	if (updating_translations)
 		return;
 
-	if (!GlobalConfig::get_singleton()->has("locale/translation_remaps"))
+	if (!ProjectSettings::get_singleton()->has("locale/translation_remaps"))
 		return;
 
-	Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+	Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 
 	TreeItem *k = translation_remap->get_selected();
 	ERR_FAIL_COND(!k);
@@ -1127,8 +1193,8 @@ void ProjectSettings::_translation_res_option_delete(Object *p_item, int p_colum
 	remaps[key] = r;
 
 	undo_redo->create_action(TTR("Remove Resource Remap Option"));
-	undo_redo->add_do_property(GlobalConfig::get_singleton(), "locale/translation_remaps", remaps);
-	undo_redo->add_undo_property(GlobalConfig::get_singleton(), "locale/translation_remaps", GlobalConfig::get_singleton()->get("locale/translation_remaps"));
+	undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
+	undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
 	undo_redo->add_do_method(this, "_update_translations");
 	undo_redo->add_undo_method(this, "_update_translations");
 	undo_redo->add_do_method(this, "_settings_changed");
@@ -1136,7 +1202,7 @@ void ProjectSettings::_translation_res_option_delete(Object *p_item, int p_colum
 	undo_redo->commit_action();
 }
 
-void ProjectSettings::_update_translations() {
+void ProjectSettingsEditor::_update_translations() {
 
 	//update translations
 
@@ -1148,9 +1214,9 @@ void ProjectSettings::_update_translations() {
 	translation_list->clear();
 	TreeItem *root = translation_list->create_item(NULL);
 	translation_list->set_hide_root(true);
-	if (GlobalConfig::get_singleton()->has("locale/translations")) {
+	if (ProjectSettings::get_singleton()->has("locale/translations")) {
 
-		PoolStringArray translations = GlobalConfig::get_singleton()->get("locale/translations");
+		PoolStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
 		for (int i = 0; i < translations.size(); i++) {
 
 			TreeItem *t = translation_list->create_item(root);
@@ -1186,9 +1252,9 @@ void ProjectSettings::_update_translations() {
 		langnames += names[i];
 	}
 
-	if (GlobalConfig::get_singleton()->has("locale/translation_remaps")) {
+	if (ProjectSettings::get_singleton()->has("locale/translation_remaps")) {
 
-		Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps");
+		Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
 		List<Variant> rk;
 		remaps.get_key_list(&rk);
 		Vector<String> keys;
@@ -1241,7 +1307,7 @@ void ProjectSettings::_update_translations() {
 	updating_translations = false;
 }
 
-void ProjectSettings::_toggle_search_bar(bool p_pressed) {
+void ProjectSettingsEditor::_toggle_search_bar(bool p_pressed) {
 
 	globals_editor->get_property_editor()->set_use_filter(p_pressed);
 
@@ -1258,7 +1324,7 @@ void ProjectSettings::_toggle_search_bar(bool p_pressed) {
 	}
 }
 
-void ProjectSettings::_clear_search_box() {
+void ProjectSettingsEditor::_clear_search_box() {
 
 	if (search_box->get_text() == "")
 		return;
@@ -1267,52 +1333,54 @@ void ProjectSettings::_clear_search_box() {
 	globals_editor->get_property_editor()->update_tree();
 }
 
-void ProjectSettings::set_plugins_page() {
+void ProjectSettingsEditor::set_plugins_page() {
 
 	tab_container->set_current_tab(plugin_settings->get_index());
 }
 
-void ProjectSettings::_bind_methods() {
-
-	ClassDB::bind_method(D_METHOD("_item_selected"), &ProjectSettings::_item_selected);
-	ClassDB::bind_method(D_METHOD("_item_add"), &ProjectSettings::_item_add);
-	ClassDB::bind_method(D_METHOD("_item_adds"), &ProjectSettings::_item_adds);
-	ClassDB::bind_method(D_METHOD("_item_del"), &ProjectSettings::_item_del);
-	ClassDB::bind_method(D_METHOD("_item_checked"), &ProjectSettings::_item_checked);
-	ClassDB::bind_method(D_METHOD("_save"), &ProjectSettings::_save);
-	ClassDB::bind_method(D_METHOD("_action_add"), &ProjectSettings::_action_add);
-	ClassDB::bind_method(D_METHOD("_action_adds"), &ProjectSettings::_action_adds);
-	ClassDB::bind_method(D_METHOD("_action_selected"), &ProjectSettings::_action_selected);
-	ClassDB::bind_method(D_METHOD("_action_edited"), &ProjectSettings::_action_edited);
-	ClassDB::bind_method(D_METHOD("_action_activated"), &ProjectSettings::_action_activated);
-	ClassDB::bind_method(D_METHOD("_action_button_pressed"), &ProjectSettings::_action_button_pressed);
-	ClassDB::bind_method(D_METHOD("_update_actions"), &ProjectSettings::_update_actions);
-	ClassDB::bind_method(D_METHOD("_wait_for_key"), &ProjectSettings::_wait_for_key);
-	ClassDB::bind_method(D_METHOD("_add_item"), &ProjectSettings::_add_item, DEFVAL(Variant()));
-	ClassDB::bind_method(D_METHOD("_device_input_add"), &ProjectSettings::_device_input_add);
-	ClassDB::bind_method(D_METHOD("_press_a_key_confirm"), &ProjectSettings::_press_a_key_confirm);
-	ClassDB::bind_method(D_METHOD("_settings_prop_edited"), &ProjectSettings::_settings_prop_edited);
-	ClassDB::bind_method(D_METHOD("_copy_to_platform"), &ProjectSettings::_copy_to_platform);
-	ClassDB::bind_method(D_METHOD("_update_translations"), &ProjectSettings::_update_translations);
-	ClassDB::bind_method(D_METHOD("_translation_delete"), &ProjectSettings::_translation_delete);
-	ClassDB::bind_method(D_METHOD("_settings_changed"), &ProjectSettings::_settings_changed);
-	ClassDB::bind_method(D_METHOD("_translation_add"), &ProjectSettings::_translation_add);
-	ClassDB::bind_method(D_METHOD("_translation_file_open"), &ProjectSettings::_translation_file_open);
-
-	ClassDB::bind_method(D_METHOD("_translation_res_add"), &ProjectSettings::_translation_res_add);
-	ClassDB::bind_method(D_METHOD("_translation_res_file_open"), &ProjectSettings::_translation_res_file_open);
-	ClassDB::bind_method(D_METHOD("_translation_res_option_add"), &ProjectSettings::_translation_res_option_add);
-	ClassDB::bind_method(D_METHOD("_translation_res_option_file_open"), &ProjectSettings::_translation_res_option_file_open);
-	ClassDB::bind_method(D_METHOD("_translation_res_select"), &ProjectSettings::_translation_res_select);
-	ClassDB::bind_method(D_METHOD("_translation_res_option_changed"), &ProjectSettings::_translation_res_option_changed);
-	ClassDB::bind_method(D_METHOD("_translation_res_delete"), &ProjectSettings::_translation_res_delete);
-	ClassDB::bind_method(D_METHOD("_translation_res_option_delete"), &ProjectSettings::_translation_res_option_delete);
-
-	ClassDB::bind_method(D_METHOD("_clear_search_box"), &ProjectSettings::_clear_search_box);
-	ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettings::_toggle_search_bar);
+void ProjectSettingsEditor::_bind_methods() {
+
+	ClassDB::bind_method(D_METHOD("_item_selected"), &ProjectSettingsEditor::_item_selected);
+	ClassDB::bind_method(D_METHOD("_item_add"), &ProjectSettingsEditor::_item_add);
+	ClassDB::bind_method(D_METHOD("_item_adds"), &ProjectSettingsEditor::_item_adds);
+	ClassDB::bind_method(D_METHOD("_item_del"), &ProjectSettingsEditor::_item_del);
+	ClassDB::bind_method(D_METHOD("_item_checked"), &ProjectSettingsEditor::_item_checked);
+	ClassDB::bind_method(D_METHOD("_save"), &ProjectSettingsEditor::_save);
+	ClassDB::bind_method(D_METHOD("_action_add"), &ProjectSettingsEditor::_action_add);
+	ClassDB::bind_method(D_METHOD("_action_adds"), &ProjectSettingsEditor::_action_adds);
+	ClassDB::bind_method(D_METHOD("_action_selected"), &ProjectSettingsEditor::_action_selected);
+	ClassDB::bind_method(D_METHOD("_action_edited"), &ProjectSettingsEditor::_action_edited);
+	ClassDB::bind_method(D_METHOD("_action_activated"), &ProjectSettingsEditor::_action_activated);
+	ClassDB::bind_method(D_METHOD("_action_button_pressed"), &ProjectSettingsEditor::_action_button_pressed);
+	ClassDB::bind_method(D_METHOD("_update_actions"), &ProjectSettingsEditor::_update_actions);
+	ClassDB::bind_method(D_METHOD("_wait_for_key"), &ProjectSettingsEditor::_wait_for_key);
+	ClassDB::bind_method(D_METHOD("_add_item"), &ProjectSettingsEditor::_add_item, DEFVAL(Variant()));
+	ClassDB::bind_method(D_METHOD("_device_input_add"), &ProjectSettingsEditor::_device_input_add);
+	ClassDB::bind_method(D_METHOD("_press_a_key_confirm"), &ProjectSettingsEditor::_press_a_key_confirm);
+	ClassDB::bind_method(D_METHOD("_settings_prop_edited"), &ProjectSettingsEditor::_settings_prop_edited);
+	ClassDB::bind_method(D_METHOD("_copy_to_platform"), &ProjectSettingsEditor::_copy_to_platform);
+	ClassDB::bind_method(D_METHOD("_update_translations"), &ProjectSettingsEditor::_update_translations);
+	ClassDB::bind_method(D_METHOD("_translation_delete"), &ProjectSettingsEditor::_translation_delete);
+	ClassDB::bind_method(D_METHOD("_settings_changed"), &ProjectSettingsEditor::_settings_changed);
+	ClassDB::bind_method(D_METHOD("_translation_add"), &ProjectSettingsEditor::_translation_add);
+	ClassDB::bind_method(D_METHOD("_translation_file_open"), &ProjectSettingsEditor::_translation_file_open);
+
+	ClassDB::bind_method(D_METHOD("_translation_res_add"), &ProjectSettingsEditor::_translation_res_add);
+	ClassDB::bind_method(D_METHOD("_translation_res_file_open"), &ProjectSettingsEditor::_translation_res_file_open);
+	ClassDB::bind_method(D_METHOD("_translation_res_option_add"), &ProjectSettingsEditor::_translation_res_option_add);
+	ClassDB::bind_method(D_METHOD("_translation_res_option_file_open"), &ProjectSettingsEditor::_translation_res_option_file_open);
+	ClassDB::bind_method(D_METHOD("_translation_res_select"), &ProjectSettingsEditor::_translation_res_select);
+	ClassDB::bind_method(D_METHOD("_translation_res_option_changed"), &ProjectSettingsEditor::_translation_res_option_changed);
+	ClassDB::bind_method(D_METHOD("_translation_res_delete"), &ProjectSettingsEditor::_translation_res_delete);
+	ClassDB::bind_method(D_METHOD("_translation_res_option_delete"), &ProjectSettingsEditor::_translation_res_option_delete);
+
+	ClassDB::bind_method(D_METHOD("_clear_search_box"), &ProjectSettingsEditor::_clear_search_box);
+	ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettingsEditor::_toggle_search_bar);
+
+	ClassDB::bind_method(D_METHOD("_copy_to_platform_about_to_show"), &ProjectSettingsEditor::_copy_to_platform_about_to_show);
 }
 
-ProjectSettings::ProjectSettings(EditorData *p_data) {
+ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
 
 	singleton = this;
 	set_title(TTR("Project Settings (project.godot)"));
@@ -1388,11 +1456,6 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 	add->set_text(TTR("Add"));
 	add->connect("pressed", this, "_item_add");
 
-	Button *del = memnew(Button);
-	add_prop_bar->add_child(del);
-	del->set_text(TTR("Del"));
-	del->connect("pressed", this, "_item_del");
-
 	search_bar = memnew(HBoxContainer);
 	search_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL);
 	hbc->add_child(search_bar);
@@ -1409,6 +1472,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 	globals_editor = memnew(SectionedPropertyEditor);
 	props_base->add_child(globals_editor);
 	globals_editor->get_property_editor()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo());
+	globals_editor->get_property_editor()->set_property_selectable(true);
 	//globals_editor->hide_top_label();
 	globals_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
 	globals_editor->register_search_box(search_box);
@@ -1430,15 +1494,17 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 	save->connect("pressed",this,"_save");
 */
 
-	hbc = memnew(HBoxContainer);
-	props_base->add_child(hbc);
+	Button *del = memnew(Button);
+	hbc->add_child(del);
+	del->set_text(TTR("Delete"));
+	del->connect("pressed", this, "_item_del");
 
-	popup_platform = memnew(MenuButton);
-	popup_platform->set_text(TTR("Copy To Platform.."));
-	popup_platform->set_disabled(true);
-	hbc->add_child(popup_platform);
+	add_prop_bar->add_child(memnew(VSeparator));
 
-	hbc->add_spacer();
+	popup_copy_to_feature = memnew(MenuButton);
+	popup_copy_to_feature->set_text(TTR("Override For.."));
+	popup_copy_to_feature->set_disabled(true);
+	add_prop_bar->add_child(popup_copy_to_feature);
 
 	/*List<StringName> ep;
 	EditorImportExport::get_singleton()->get_export_platforms(&ep);
@@ -1446,11 +1512,13 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 
 	for(List<StringName>::Element *E=ep.front();E;E=E->next()) {
 
-		popup_platform->get_popup()->add_item( E->get() );
+		popup_copy_to_feature->get_popup()->add_item( E->get() );
 
 	}*/
 
-	popup_platform->get_popup()->connect("id_pressed", this, "_copy_to_platform");
+	popup_copy_to_feature->get_popup()->connect("id_pressed", this, "_copy_to_platform");
+	popup_copy_to_feature->get_popup()->connect("about_to_show", this, "_copy_to_platform_about_to_show");
+
 	get_ok()->set_text(TTR("Close"));
 	set_hide_on_ok(true);
 
@@ -1665,7 +1733,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 
 	timer = memnew(Timer);
 	timer->set_wait_time(1.5);
-	timer->connect("timeout", GlobalConfig::get_singleton(), "save");
+	timer->connect("timeout", ProjectSettings::get_singleton(), "save");
 	timer->set_one_shot(true);
 	add_child(timer);
 

+ 9 - 7
editor/project_settings.h → editor/project_settings_editor.h

@@ -40,8 +40,8 @@
 
 //#include "project_export_settings.h"
 
-class ProjectSettings : public AcceptDialog {
-	GDCLASS(ProjectSettings, AcceptDialog);
+class ProjectSettingsEditor : public AcceptDialog {
+	GDCLASS(ProjectSettingsEditor, AcceptDialog);
 
 	enum InputType {
 		INPUT_KEY,
@@ -78,7 +78,7 @@ class ProjectSettings : public AcceptDialog {
 	SpinBox *device_id;
 	OptionButton *device_index;
 	Label *device_index_label;
-	MenuButton *popup_platform;
+	MenuButton *popup_copy_to_feature;
 
 	LineEdit *action_name;
 	Tree *input_editor;
@@ -145,9 +145,11 @@ class ProjectSettings : public AcceptDialog {
 	void _toggle_search_bar(bool p_pressed);
 	void _clear_search_box();
 
-	ProjectSettings();
+	void _copy_to_platform_about_to_show();
 
-	static ProjectSettings *singleton;
+	ProjectSettingsEditor();
+
+	static ProjectSettingsEditor *singleton;
 
 protected:
 	void _notification(int p_what);
@@ -155,13 +157,13 @@ protected:
 
 public:
 	void add_translation(const String &p_translation);
-	static ProjectSettings *get_singleton() { return singleton; }
+	static ProjectSettingsEditor *get_singleton() { return singleton; }
 	void popup_project_settings();
 	void set_plugins_page();
 
 	void queue_save();
 
-	ProjectSettings(EditorData *p_data);
+	ProjectSettingsEditor(EditorData *p_data);
 };
 
 #endif // PROJECT_SETTINGS_H

+ 37 - 7
editor/property_editor.cpp

@@ -37,8 +37,6 @@
 #include "editor_help.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
-#include "global_config.h"
 #include "io/image_loader.h"
 #include "io/resource_loader.h"
 #include "multi_node_edit.h"
@@ -46,6 +44,8 @@
 #include "os/keyboard.h"
 #include "pair.h"
 #include "print_string.h"
+#include "project_settings.h"
+#include "project_settings.h"
 #include "property_selector.h"
 #include "scene/gui/label.h"
 #include "scene/main/viewport.h"
@@ -415,7 +415,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
 
 						int idx = i * 10 + j;
 						CheckBox *c = checks20[idx];
-						c->set_text(GlobalConfig::get_singleton()->get(basename + "/layer_" + itos(idx + 1)));
+						c->set_text(ProjectSettings::get_singleton()->get(basename + "/layer_" + itos(idx + 1)));
 						c->set_pressed(flgs & (1 << (i * 10 + j)));
 						c->show();
 					}
@@ -1019,7 +1019,7 @@ void CustomPropertyEditor::_file_selected(String p_file) {
 
 			if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_DIR) {
 
-				v = GlobalConfig::get_singleton()->localize_path(p_file);
+				v = ProjectSettings::get_singleton()->localize_path(p_file);
 				emit_signal("variant_changed");
 				hide();
 			}
@@ -3002,8 +3002,18 @@ void PropertyEditor::update_tree() {
 
 		String name = (basename.find("/") != -1) ? basename.right(basename.find_last("/") + 1) : basename;
 
-		if (capitalize_paths)
-			name = name.camelcase_to_underscore().capitalize();
+		if (capitalize_paths) {
+			int dot = name.find(".");
+			if (dot != -1) {
+				String ov = name.right(dot);
+				name = name.substr(0, dot);
+				name = name.camelcase_to_underscore().capitalize();
+				name += ov;
+
+			} else {
+				name = name.camelcase_to_underscore().capitalize();
+			}
+		}
 
 		String path = basename.left(basename.find_last("/"));
 
@@ -3046,7 +3056,7 @@ void PropertyEditor::update_tree() {
 			//item->set_custom_bg_color(1,col);
 		}
 		item->set_editable(0, false);
-		item->set_selectable(0, false);
+		item->set_selectable(0, property_selectable);
 
 		if (p.usage & PROPERTY_USAGE_CHECKABLE) {
 
@@ -3059,6 +3069,18 @@ void PropertyEditor::update_tree() {
 		item->set_text(0, name);
 		item->set_tooltip(0, p.name);
 
+		if (name.find(".") != -1) {
+			Color textcol = get_color("font_color", "Tree");
+			textcol.a *= 0.5;
+			//override :D
+			item->set_custom_color(0, textcol);
+			item->set_custom_color(1, textcol);
+
+			Color iconcol(1, 1, 1, 0.6);
+			item->set_icon_color(0, iconcol);
+			item->set_icon_color(1, iconcol);
+		}
+
 		if (use_doc_hints) {
 			StringName setter;
 			StringName type;
@@ -4308,6 +4330,11 @@ void PropertyEditor::register_text_enter(Node *p_line_edit) {
 		search_box->connect("text_changed", this, "_filter_changed");
 }
 
+void PropertyEditor::set_property_selectable(bool p_selectable) {
+	property_selectable = p_selectable;
+	update_tree();
+}
+
 void PropertyEditor::set_subsection_selectable(bool p_selectable) {
 
 	if (p_selectable == subsection_selectable)
@@ -4394,6 +4421,7 @@ PropertyEditor::PropertyEditor() {
 	updating_folding = true;
 	use_filter = false;
 	subsection_selectable = false;
+	property_selectable = false;
 	show_type_icons = EDITOR_DEF("interface/show_type_icons", false);
 }
 
@@ -4647,6 +4675,8 @@ void SectionedPropertyEditor::update_category_list() {
 	if (section_map.has(selected_category)) {
 		section_map[selected_category]->select(0);
 	}
+
+	editor->update_tree();
 }
 
 void SectionedPropertyEditor::register_search_box(LineEdit *p_box) {

+ 2 - 0
editor/property_editor.h

@@ -191,6 +191,7 @@ class PropertyEditor : public Control {
 	bool subsection_selectable;
 	bool hide_script;
 	bool use_folding;
+	bool property_selectable;
 
 	bool updating_folding;
 
@@ -288,6 +289,7 @@ public:
 	void register_text_enter(Node *p_line_edit);
 
 	void set_subsection_selectable(bool p_selectable);
+	void set_property_selectable(bool p_selectable);
 
 	void set_use_folding(bool p_enable);
 	PropertyEditor();

+ 2 - 2
editor/resources_dock.cpp

@@ -32,10 +32,10 @@
 #include "editor_file_system.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "project_settings.h"
+#include "project_settings_editor.h"
 
 void ResourcesDock::_tool_selected(int p_tool) {
 
@@ -124,7 +124,7 @@ void ResourcesDock::save_resource(const String &p_path, const Ref<Resource> &p_r
 		flg|=ResourceSaver::FLAG_RELATIVE_PATHS;
 	*/
 
-	String path = GlobalConfig::get_singleton()->localize_path(p_path);
+	String path = ProjectSettings::get_singleton()->localize_path(p_path);
 	Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
 
 	if (err != OK) {

+ 2 - 2
editor/scene_tree_dock.cpp

@@ -37,7 +37,7 @@
 #include "editor/plugins/spatial_editor_plugin.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "multi_node_edit.h"
 #include "os/keyboard.h"
 #include "scene/main/viewport.h"
@@ -183,7 +183,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
 			}
 		}
 
-		instanced_scene->set_filename(GlobalConfig::get_singleton()->localize_path(p_files[i]));
+		instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_files[i]));
 
 		instances.push_back(instanced_scene);
 	}

+ 4 - 4
editor/script_create_dialog.cpp

@@ -31,7 +31,7 @@
 
 #include "editor/editor_scale.h"
 #include "editor_file_system.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_saver.h"
 #include "os/file_access.h"
 #include "script_language.h"
@@ -167,7 +167,7 @@ void ScriptCreateDialog::_create_new() {
 		scr->set_name(cname);
 
 	if (!is_built_in) {
-		String lpath = GlobalConfig::get_singleton()->localize_path(file_path->get_text());
+		String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text());
 		scr->set_path(lpath);
 		Error err = ResourceSaver::save(lpath, scr, ResourceSaver::FLAG_CHANGE_PATH);
 		if (err != OK) {
@@ -305,7 +305,7 @@ void ScriptCreateDialog::_browse_path(bool browse_parent) {
 
 void ScriptCreateDialog::_file_selected(const String &p_file) {
 
-	String p = GlobalConfig::get_singleton()->localize_path(p_file);
+	String p = ProjectSettings::get_singleton()->localize_path(p_file);
 	if (is_browsing_parent) {
 		parent_name->set_text("\"" + p + "\"");
 		_class_name_changed("\"" + p + "\"");
@@ -327,7 +327,7 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
 		return;
 	}
 
-	p = GlobalConfig::get_singleton()->localize_path(p);
+	p = ProjectSettings::get_singleton()->localize_path(p);
 	if (!p.begins_with("res://")) {
 		_msg_path_valid(false, TTR("Path is not local"));
 		_update_dialog();

+ 1 - 1
editor/script_editor_debugger.cpp

@@ -32,7 +32,7 @@
 #include "editor_node.h"
 #include "editor_profiler.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "main/performance.h"
 #include "property_editor.h"
 #include "scene/gui/dialogs.h"

+ 1 - 1
editor/settings_config_dialog.cpp

@@ -32,7 +32,7 @@
 #include "editor_file_system.h"
 #include "editor_node.h"
 #include "editor_settings.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/keyboard.h"
 #include "scene/gui/margin_container.h"
 

+ 31 - 26
main/main.cpp

@@ -31,10 +31,10 @@
 #include "app_icon.gen.h"
 #include "core/register_core_types.h"
 #include "drivers/register_driver_types.h"
-#include "global_config.h"
 #include "message_queue.h"
 #include "modules/register_module_types.h"
 #include "os/os.h"
+#include "project_settings.h"
 #include "scene/register_scene_types.h"
 #include "script_debugger_local.h"
 #include "script_debugger_remote.h"
@@ -74,7 +74,7 @@
 #include "translation.h"
 #include "version.h"
 
-static GlobalConfig *globals = NULL;
+static ProjectSettings *globals = NULL;
 static Engine *engine = NULL;
 static InputMap *input_map = NULL;
 static bool _start_success = false;
@@ -205,14 +205,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 
 	Thread::_main_thread_id = Thread::get_caller_ID();
 
-	globals = memnew(GlobalConfig);
+	globals = memnew(ProjectSettings);
 	input_map = memnew(InputMap);
 
 	register_core_settings(); //here globals is present
 
 	translation_server = memnew(TranslationServer);
 	performance = memnew(Performance);
-	globals->add_singleton(GlobalConfig::Singleton("Performance", performance));
+	globals->add_singleton(ProjectSettings::Singleton("Performance", performance));
 
 	MAIN_PRINT("Main: Parse CMDLine");
 
@@ -529,7 +529,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 
 			if (I->next()) {
 
-				GlobalConfig::get_singleton()->set("editor_scene", game_path = I->next()->get());
+				ProjectSettings::get_singleton()->set("editor_scene", game_path = I->next()->get());
 			} else {
 				goto error;
 			}
@@ -551,7 +551,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 			if (I->next()) {
 
 				int editor_pid = I->next()->get().to_int();
-				GlobalConfig::get_singleton()->set("editor_pid", editor_pid);
+				ProjectSettings::get_singleton()->set("editor_pid", editor_pid);
 				N = I->next()->next();
 			} else {
 				goto error;
@@ -642,7 +642,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 #ifdef TOOLS_ENABLED
 	if (editor) {
 		packed_data->set_disabled(true);
-		globals->set_disable_platform_override(true);
+		globals->set_disable_feature_overrides(true);
 		StreamPeerSSL::initialize_certs = false; //will be initialized by editor
 	}
 
@@ -665,10 +665,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 		use_custom_res = false;
 	}
 
-	if (bool(GlobalConfig::get_singleton()->get("application/run/disable_stdout"))) {
+	if (bool(ProjectSettings::get_singleton()->get("application/run/disable_stdout"))) {
 		quiet_stdout = true;
 	}
-	if (bool(GlobalConfig::get_singleton()->get("application/run/disable_stderr"))) {
+	if (bool(ProjectSettings::get_singleton()->get("application/run/disable_stderr"))) {
 		_print_error_enabled = false;
 	};
 
@@ -679,7 +679,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 
 #ifdef TOOLS_ENABLED
 
-	if (main_args.size() == 0 && (!GlobalConfig::get_singleton()->has("application/run/main_loop_type")) && (!GlobalConfig::get_singleton()->has("application/run/main_scene") || String(GlobalConfig::get_singleton()->get("application/run/main_scene")) == ""))
+	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")) == ""))
 		use_custom_res = false; //project manager (run without arguments)
 
 #endif
@@ -724,6 +724,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 	use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", use_vsync);
 	GLOBAL_DEF("display/window/size/test_width", 0);
 	GLOBAL_DEF("display/window/size/test_height", 0);
+	GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2);
+	GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3);
+
 	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) {
@@ -812,7 +815,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 
 	message_queue = memnew(MessageQueue);
 
-	GlobalConfig::get_singleton()->register_global_defaults();
+	ProjectSettings::get_singleton()->register_global_defaults();
 
 	if (p_second_phase)
 		return setup2();
@@ -913,7 +916,7 @@ Error Main::setup2() {
 	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);
-		GlobalConfig::get_singleton()->set_custom_property_info("application/boot_splash/image", PropertyInfo(Variant::STRING, "application/boot_splash/image", PROPERTY_HINT_FILE, "*.png"));
+		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;
 
@@ -933,7 +936,7 @@ Error Main::setup2() {
 			VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg, boot_logo_scale);
 #ifndef TOOLS_ENABLED
 //no tools, so free the boot logo (no longer needed)
-//GlobalConfig::get_singleton()->set("application/boot_logo",Image());
+//ProjectSettings::get_singleton()->set("application/boot_logo",Image());
 #endif
 
 		} else {
@@ -958,7 +961,7 @@ Error Main::setup2() {
 	MAIN_PRINT("Main: END");
 
 	GLOBAL_DEF("application/config/icon", String());
-	GlobalConfig::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
+	ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
 
 	if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false))) {
 		if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton() && !editor) {
@@ -977,15 +980,15 @@ Error Main::setup2() {
 
 	GLOBAL_DEF("display/mouse_cursor/custom_image", String());
 	GLOBAL_DEF("display/mouse_cursor/custom_image_hotspot", Vector2());
-	GlobalConfig::get_singleton()->set_custom_property_info("display/mouse_cursor/custom_image", PropertyInfo(Variant::STRING, "display/mouse_cursor/custom_image", PROPERTY_HINT_FILE, "*.png,*.webp"));
+	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(GlobalConfig::get_singleton()->get("display/mouse_cursor/custom_image")) != String()) {
+	if (String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image")) != String()) {
 
 		//print_line("use custom cursor");
-		Ref<Texture> cursor = ResourceLoader::load(GlobalConfig::get_singleton()->get("display/mouse_cursor/custom_image"));
+		Ref<Texture> cursor = ResourceLoader::load(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"));
 		if (cursor.is_valid()) {
 			//print_line("loaded ok");
-			Vector2 hotspot = GlobalConfig::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
+			Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
 			Input::get_singleton()->set_custom_mouse_cursor(cursor, hotspot);
 		}
 	}
@@ -1276,7 +1279,7 @@ bool Main::start() {
 
 			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));
-			String appname = GlobalConfig::get_singleton()->get("application/config/name");
+			String appname = ProjectSettings::get_singleton()->get("application/config/name");
 			appname = TranslationServer::get_singleton()->translate(appname);
 			OS::get_singleton()->set_window_title(appname);
 
@@ -1291,12 +1294,14 @@ bool Main::start() {
 			sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q1_subdiv));
 			sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q2_subdiv));
 			sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q3_subdiv));
+			Viewport::Usage usage = Viewport::Usage(int(GLOBAL_GET("rendering/quality/intended_usage/framebuffer_allocation")));
+			sml->get_root()->set_usage(usage);
 
 		} else {
 			GLOBAL_DEF("display/window/stretch/mode", "disabled");
-			GlobalConfig::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
+			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");
-			GlobalConfig::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"));
+			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"));
 			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));
 		}
@@ -1311,7 +1316,7 @@ bool Main::start() {
 
 				if (!absolute) {
 
-					if (GlobalConfig::get_singleton()->is_using_datapack()) {
+					if (ProjectSettings::get_singleton()->is_using_datapack()) {
 
 						local_game_path = "res://" + local_game_path;
 
@@ -1334,7 +1339,7 @@ bool Main::start() {
 				}
 			}
 
-			local_game_path = GlobalConfig::get_singleton()->localize_path(local_game_path);
+			local_game_path = ProjectSettings::get_singleton()->localize_path(local_game_path);
 
 #ifdef TOOLS_ENABLED
 			if (editor) {
@@ -1360,7 +1365,7 @@ bool Main::start() {
 			if (game_path != "" || script != "") {
 				//autoload
 				List<PropertyInfo> props;
-				GlobalConfig::get_singleton()->get_property_list(&props);
+				ProjectSettings::get_singleton()->get_property_list(&props);
 
 				//first pass, add the constants so they exist before any script is loaded
 				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
@@ -1369,7 +1374,7 @@ bool Main::start() {
 					if (!s.begins_with("autoload/"))
 						continue;
 					String name = s.get_slicec('/', 1);
-					String path = GlobalConfig::get_singleton()->get(s);
+					String path = ProjectSettings::get_singleton()->get(s);
 					bool global_var = false;
 					if (path.begins_with("*")) {
 						global_var = true;
@@ -1390,7 +1395,7 @@ bool Main::start() {
 					if (!s.begins_with("autoload/"))
 						continue;
 					String name = s.get_slicec('/', 1);
-					String path = GlobalConfig::get_singleton()->get(s);
+					String path = ProjectSettings::get_singleton()->get(s);
 					bool global_var = false;
 					if (path.begins_with("*")) {
 						global_var = true;

+ 5 - 5
main/tests/test_io.cpp

@@ -31,7 +31,7 @@
 
 #ifdef MINIZIP_ENABLED
 
-#include "core/global_config.h"
+#include "core/project_settings.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "os/dir_access.h"
@@ -91,10 +91,10 @@ MainLoop *test() {
 	ResourceSaver::save("test_data/rock.xml", texture);
 
 	print_line("localize paths");
-	print_line(GlobalConfig::get_singleton()->localize_path("algo.xml"));
-	print_line(GlobalConfig::get_singleton()->localize_path("c:\\windows\\algo.xml"));
-	print_line(GlobalConfig::get_singleton()->localize_path(GlobalConfig::get_singleton()->get_resource_path() + "/something/something.xml"));
-	print_line(GlobalConfig::get_singleton()->localize_path("somedir/algo.xml"));
+	print_line(ProjectSettings::get_singleton()->localize_path("algo.xml"));
+	print_line(ProjectSettings::get_singleton()->localize_path("c:\\windows\\algo.xml"));
+	print_line(ProjectSettings::get_singleton()->localize_path(ProjectSettings::get_singleton()->get_resource_path() + "/something/something.xml"));
+	print_line(ProjectSettings::get_singleton()->localize_path("somedir/algo.xml"));
 
 	{
 

+ 2 - 2
modules/gdnative/api_generator.cpp

@@ -32,8 +32,8 @@
 #ifdef TOOLS_ENABLED
 
 #include "class_db.h"
-#include "core/global_config.h"
 #include "core/global_constants.h"
+#include "core/project_settings.h"
 #include "os/file_access.h"
 
 // helper stuff
@@ -150,7 +150,7 @@ List<ClassAPI> generate_c_api_classes() {
 			if (name.begins_with("_")) {
 				name.remove(0);
 			}
-			class_api.is_singleton = GlobalConfig::get_singleton()->has_singleton(name);
+			class_api.is_singleton = ProjectSettings::get_singleton()->has_singleton(name);
 		}
 		class_api.is_instanciable = !class_api.is_singleton && ClassDB::can_instance(class_name);
 

+ 3 - 3
modules/gdnative/gdnative.cpp

@@ -29,11 +29,11 @@
 /*************************************************************************/
 #include "gdnative.h"
 
-#include "global_config.h"
 #include "global_constants.h"
 #include "io/file_access_encrypted.h"
 #include "os/file_access.h"
 #include "os/os.h"
+#include "project_settings.h"
 
 #include "scene/main/scene_tree.h"
 #include "scene/resources/scene_format_text.h"
@@ -573,7 +573,7 @@ Error GDNativeLibrary::_initialize() {
 	}
 	ERR_FAIL_COND_V(platform_file == "", ERR_DOES_NOT_EXIST);
 
-	StringName path = GlobalConfig::get_singleton()->globalize_path(platform_file);
+	StringName path = ProjectSettings::get_singleton()->globalize_path(platform_file);
 
 	GDNativeLibrary::currently_initialized_library = this;
 
@@ -1083,7 +1083,7 @@ void GDNativeScriptLanguage::init() {
 	// TODO: Expose globals
 	GLOBAL_DEF("gdnative/default_gdnativelibrary", "");
 	PropertyInfo prop_info(Variant::STRING, "gdnative/default_gdnativelibrary", PROPERTY_HINT_FILE, "tres,res,dllib");
-	GlobalConfig::get_singleton()->set_custom_property_info("gdnative/default_gdnativelibrary", prop_info);
+	ProjectSettings::get_singleton()->set_custom_property_info("gdnative/default_gdnativelibrary", prop_info);
 
 // generate bindings
 #if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)

+ 2 - 2
modules/gdnative/godot.cpp

@@ -32,8 +32,8 @@
 #include "class_db.h"
 #include "error_macros.h"
 #include "gdnative.h"
-#include "global_config.h"
 #include "global_constants.h"
+#include "project_settings.h"
 #include "variant.h"
 
 #ifdef __cplusplus
@@ -93,7 +93,7 @@ void GDAPI godot_object_destroy(godot_object *p_o) {
 // Singleton API
 
 godot_object GDAPI *godot_global_get_singleton(char *p_name) {
-	return (godot_object *)GlobalConfig::get_singleton()->get_singleton_object(String(p_name));
+	return (godot_object *)ProjectSettings::get_singleton()->get_singleton_object(String(p_name));
 } // result shouldn't be freed
 
 // MethodBind API

+ 10 - 10
modules/gdscript/gd_editor.cpp

@@ -30,7 +30,7 @@
 #include "editor/editor_settings.h"
 #include "gd_compiler.h"
 #include "gd_script.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/file_access.h"
 #ifdef TOOLS_ENABLED
 #include "editor/editor_file_system.h"
@@ -638,7 +638,7 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser:
 									String which = arg1.get_slice("/", 2);
 									if (which != "") {
 										List<PropertyInfo> props;
-										GlobalConfig::get_singleton()->get_property_list(&props);
+										ProjectSettings::get_singleton()->get_property_list(&props);
 										//print_line("find singleton");
 
 										for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
@@ -650,7 +650,7 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser:
 											String name = s.get_slice("/", 1);
 											//print_line("name: "+name+", which: "+which);
 											if (name == which) {
-												String script = GlobalConfig::get_singleton()->get(s);
+												String script = ProjectSettings::get_singleton()->get(s);
 
 												if (!script.begins_with("res://")) {
 													script = "res://" + script;
@@ -1105,7 +1105,7 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con
 
 	//autoloads as singletons
 	List<PropertyInfo> props;
-	GlobalConfig::get_singleton()->get_property_list(&props);
+	ProjectSettings::get_singleton()->get_property_list(&props);
 
 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
@@ -1115,7 +1115,7 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con
 		String name = s.get_slice("/", 1);
 		if (name == String(p_identifier)) {
 
-			String path = GlobalConfig::get_singleton()->get(s);
+			String path = ProjectSettings::get_singleton()->get(s);
 			if (path.begins_with("*")) {
 				String script = path.substr(1, path.length());
 
@@ -1344,7 +1344,7 @@ static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_o
 
 	//autoload singletons
 	List<PropertyInfo> props;
-	GlobalConfig::get_singleton()->get_property_list(&props);
+	ProjectSettings::get_singleton()->get_property_list(&props);
 
 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
@@ -1352,7 +1352,7 @@ static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_o
 		if (!s.begins_with("autoload/"))
 			continue;
 		String name = s.get_slice("/", 1);
-		String path = GlobalConfig::get_singleton()->get(s);
+		String path = ProjectSettings::get_singleton()->get(s);
 		if (path.begins_with("*")) {
 			result.insert(name);
 		}
@@ -1685,7 +1685,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N
 				if (p_argidx == 0 && (String(p_method) == "get_node" || String(p_method) == "has_node") && ClassDB::is_parent_class(id.obj_type, "Node")) {
 
 					List<PropertyInfo> props;
-					GlobalConfig::get_singleton()->get_property_list(&props);
+					ProjectSettings::get_singleton()->get_property_list(&props);
 
 					for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
@@ -2660,7 +2660,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
 
 				//guess in autoloads as singletons
 				List<PropertyInfo> props;
-				GlobalConfig::get_singleton()->get_property_list(&props);
+				ProjectSettings::get_singleton()->get_property_list(&props);
 
 				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
@@ -2670,7 +2670,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
 					String name = s.get_slice("/", 1);
 					if (name == String(p_symbol)) {
 
-						String path = GlobalConfig::get_singleton()->get(s);
+						String path = ProjectSettings::get_singleton()->get(s);
 						if (path.begins_with("*")) {
 							String script = path.substr(1, path.length());
 

+ 4 - 4
modules/gdscript/gd_script.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "gd_script.h"
 #include "gd_compiler.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "global_constants.h"
 #include "io/file_access_encrypted.h"
 #include "os/file_access.h"
@@ -1454,9 +1454,9 @@ void GDScriptLanguage::init() {
 
 	//populate singletons
 
-	List<GlobalConfig::Singleton> singletons;
-	GlobalConfig::get_singleton()->get_singletons(&singletons);
-	for (List<GlobalConfig::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
+	List<ProjectSettings::Singleton> singletons;
+	ProjectSettings::get_singleton()->get_singletons(&singletons);
+	for (List<ProjectSettings::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
 
 		_add_global(E->get().name, E->get().ptr);
 	}

+ 2 - 2
modules/openssl/stream_peer_openssl.cpp

@@ -560,7 +560,7 @@ void StreamPeerOpenSSL::initialize_ssl() {
 	ERR_load_BIO_strings(); // Load BIO error strings
 	OpenSSL_add_all_algorithms(); // Load all available encryption algorithms
 	String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
-	GlobalConfig::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
+	ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
 	if (certs_path != "") {
 
 		FileAccess *f = FileAccess::open(certs_path, FileAccess::READ);
@@ -581,7 +581,7 @@ void StreamPeerOpenSSL::initialize_ssl() {
 		}
 	}
 	String config_path = GLOBAL_DEF("network/ssl/config", "");
-	GlobalConfig::get_singleton()->set_custom_property_info("network/ssl/config", PropertyInfo(Variant::STRING, "network/ssl/config", PROPERTY_HINT_FILE, "*.cnf"));
+	ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/config", PropertyInfo(Variant::STRING, "network/ssl/config", PROPERTY_HINT_FILE, "*.cnf"));
 	if (config_path != "") {
 
 		Vector<uint8_t> data = FileAccess::get_file_as_array(config_path);

+ 1 - 1
modules/openssl/stream_peer_openssl.h

@@ -30,7 +30,7 @@
 #ifndef STREAM_PEER_OPEN_SSL_H
 #define STREAM_PEER_OPEN_SSL_H
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/stream_peer_ssl.h"
 #include "os/file_access.h"
 

+ 2 - 2
modules/theora/video_stream_theora.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "video_stream_theora.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 
 #include "thirdparty/misc/yuv2rgb.h"
@@ -728,7 +728,7 @@ void VideoStreamPlaybackTheora::play() {
 	}
 
 	playing = true;
-	delay_compensation = GlobalConfig::get_singleton()->get("audio/video_delay_compensation_ms");
+	delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms");
 	delay_compensation /= 1000.0;
 };
 

+ 1 - 1
modules/visual_script/visual_script.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "visual_script.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 #include "scene/main/node.h"
 #include "visual_script_nodes.h"

+ 5 - 5
modules/visual_script/visual_script_flow_control.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "visual_script_flow_control.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "os/keyboard.h"
 
@@ -875,7 +875,7 @@ String VisualScriptInputFilter::get_output_sequence_port_text(int p_port) const
 		case Ref<InputEvent>::ACTION: {
 
 			List<PropertyInfo> pinfo;
-			GlobalConfig::get_singleton()->get_property_list(&pinfo);
+			ProjectSettings::get_singleton()->get_property_list(&pinfo);
 			int index = 1;
 
 			text = "No Action";
@@ -1119,7 +1119,7 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
 				if (what == "action_name") {
 
 					List<PropertyInfo> pinfo;
-					GlobalConfig::get_singleton()->get_property_list(&pinfo);
+					ProjectSettings::get_singleton()->get_property_list(&pinfo);
 					int index = 1;
 
 					for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
@@ -1325,7 +1325,7 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
 				if (what == "action_name") {
 
 					List<PropertyInfo> pinfo;
-					GlobalConfig::get_singleton()->get_property_list(&pinfo);
+					ProjectSettings::get_singleton()->get_property_list(&pinfo);
 					int index = 1;
 
 					for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
@@ -1456,7 +1456,7 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
 					actions = "None";
 
 					List<PropertyInfo> pinfo;
-					GlobalConfig::get_singleton()->get_property_list(&pinfo);
+					ProjectSettings::get_singleton()->get_property_list(&pinfo);
 					Vector<String> al;
 
 					for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {

+ 8 - 8
modules/visual_script/visual_script_func_nodes.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "visual_script_func_nodes.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "io/resource_loader.h"
 #include "os/os.h"
 #include "scene/main/node.h"
@@ -347,7 +347,7 @@ void VisualScriptFunctionCall::set_singleton(const StringName &p_path) {
 		return;
 
 	singleton = p_path;
-	Object *obj = GlobalConfig::get_singleton()->get_singleton_object(singleton);
+	Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
 	if (obj) {
 		base_type = obj->get_class();
 	}
@@ -383,7 +383,7 @@ void VisualScriptFunctionCall::_update_method_cache() {
 
 	} else if (call_mode == CALL_MODE_SINGLETON) {
 
-		Object *obj = GlobalConfig::get_singleton()->get_singleton_object(singleton);
+		Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
 		if (obj) {
 			type = obj->get_class();
 			script = obj->get_script();
@@ -568,11 +568,11 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
 		if (call_mode != CALL_MODE_SINGLETON) {
 			property.usage = 0;
 		} else {
-			List<GlobalConfig::Singleton> names;
-			GlobalConfig::get_singleton()->get_singletons(&names);
+			List<ProjectSettings::Singleton> names;
+			ProjectSettings::get_singleton()->get_singletons(&names);
 			property.hint = PROPERTY_HINT_ENUM;
 			String sl;
-			for (List<GlobalConfig::Singleton>::Element *E = names.front(); E; E = E->next()) {
+			for (List<ProjectSettings::Singleton>::Element *E = names.front(); E; E = E->next()) {
 				if (sl != String())
 					sl += ",";
 				sl += E->get().name;
@@ -606,7 +606,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
 			property.hint_string = itos(get_visual_script()->get_instance_ID());
 		} else if (call_mode == CALL_MODE_SINGLETON) {
 
-			Object *obj = GlobalConfig::get_singleton()->get_singleton_object(singleton);
+			Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
 			if (obj) {
 				property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE;
 				property.hint_string = itos(obj->get_instance_ID());
@@ -867,7 +867,7 @@ public:
 			} break;
 			case VisualScriptFunctionCall::CALL_MODE_SINGLETON: {
 
-				Object *object = GlobalConfig::get_singleton()->get_singleton_object(singleton);
+				Object *object = ProjectSettings::get_singleton()->get_singleton_object(singleton);
 				if (!object) {
 					r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
 					r_error_str = "Invalid singleton name: '" + String(singleton) + "'";

+ 7 - 7
modules/visual_script/visual_script_nodes.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "visual_script_nodes.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "global_constants.h"
 #include "os/input.h"
 #include "os/os.h"
@@ -1939,13 +1939,13 @@ public:
 VisualScriptNodeInstance *VisualScriptEngineSingleton::instance(VisualScriptInstance *p_instance) {
 
 	VisualScriptNodeInstanceEngineSingleton *instance = memnew(VisualScriptNodeInstanceEngineSingleton);
-	instance->singleton = GlobalConfig::get_singleton()->get_singleton_object(singleton);
+	instance->singleton = ProjectSettings::get_singleton()->get_singleton_object(singleton);
 	return instance;
 }
 
 VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess *p_inputs, int p_output) const {
 
-	Object *obj = GlobalConfig::get_singleton()->get_singleton_object(singleton);
+	Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
 	TypeGuess tg;
 	tg.type = Variant::OBJECT;
 	if (obj) {
@@ -1963,11 +1963,11 @@ void VisualScriptEngineSingleton::_bind_methods() {
 
 	String cc;
 
-	List<GlobalConfig::Singleton> singletons;
+	List<ProjectSettings::Singleton> singletons;
 
-	GlobalConfig::get_singleton()->get_singletons(&singletons);
+	ProjectSettings::get_singleton()->get_singletons(&singletons);
 
-	for (List<GlobalConfig::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
+	for (List<ProjectSettings::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
 		if (E->get().name == "VS" || E->get().name == "PS" || E->get().name == "PS2D" || E->get().name == "AS" || E->get().name == "TS" || E->get().name == "SS" || E->get().name == "SS2D")
 			continue; //skip these, too simple named
 
@@ -3466,7 +3466,7 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
 		String actions;
 
 		List<PropertyInfo> pinfo;
-		GlobalConfig::get_singleton()->get_property_list(&pinfo);
+		ProjectSettings::get_singleton()->get_property_list(&pinfo);
 		Vector<String> al;
 
 		for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {

+ 2 - 2
modules/webm/video_stream_webm.cpp

@@ -34,7 +34,7 @@
 
 #include "mkvparser/mkvparser.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/file_access.h"
 
 #include "thirdparty/misc/yuv2rgb.h"
@@ -168,7 +168,7 @@ void VideoStreamPlaybackWebm::play() {
 
 	stop();
 
-	delay_compensation = GlobalConfig::get_singleton()->get("audio/video_delay_compensation_ms");
+	delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms");
 	delay_compensation /= 1000.0;
 
 	playing = true;

+ 1 - 1
platform/android/audio_driver_jandroid.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 #include "audio_driver_jandroid.h"
 
-#include "global_config.h"
+#include "project_settings.h"
 #include "os/os.h"
 #include "thread_jandroid.h"
 

+ 28 - 12
platform/android/export/export.cpp

@@ -31,13 +31,13 @@
 #include "editor/editor_export.h"
 #include "editor/editor_node.h"
 #include "editor/editor_settings.h"
-#include "global_config.h"
 #include "io/marshalls.h"
 #include "io/zip_io.h"
 #include "os/file_access.h"
 #include "os/os.h"
 #include "platform/android/logo.gen.h"
 #include "platform/android/run_icon.gen.h"
+#include "project_settings.h"
 #include "version.h"
 #include <string.h>
 #if 0
@@ -555,8 +555,8 @@ void EditorExportPlatformAndroid::_fix_resources(Vector<uint8_t>& p_manifest) {
 
 				String lang = str.substr(str.find_last("-")+1,str.length()).replace("-","_");
 				String prop = "application/config/name_"+lang;
-				if (GlobalConfig::get_singleton()->has(prop)) {
-					str = GlobalConfig::get_singleton()->get(prop);
+				if (ProjectSettings::get_singleton()->has(prop)) {
+					str = ProjectSettings::get_singleton()->get(prop);
 				} else {
 					str = get_project_name();
 				}
@@ -628,7 +628,7 @@ String EditorExportPlatformAndroid::get_project_name() const {
 	if (this->name!="") {
 		aname=this->name;
 	} else {
-		aname = GlobalConfig::get_singleton()->get("application/config/name");
+		aname = ProjectSettings::get_singleton()->get("application/config/name");
 
 	}
 
@@ -1144,7 +1144,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
 
 			if (!found) {
 
-				String appicon = GlobalConfig::get_singleton()->get("application/config/icon");
+				String appicon = ProjectSettings::get_singleton()->get("application/config/icon");
 				if (appicon!="" && appicon.ends_with(".png")) {
 					FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
 					if (f) {
@@ -1763,7 +1763,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
 String EditorExportPlatformAndroid::get_package_name() {
 
 	String pname = package;
-	String basename = GlobalConfig::get_singleton()->get("application/config/name");
+	String basename = ProjectSettings::get_singleton()->get("application/config/name");
 	basename=basename.to_lower();
 
 	String name;
@@ -2208,7 +2208,7 @@ class EditorExportAndroid : public EditorExportPlatform {
 		if (p_name != "") {
 			aname = p_name;
 		} else {
-			aname = GlobalConfig::get_singleton()->get("application/config/name");
+			aname = ProjectSettings::get_singleton()->get("application/config/name");
 		}
 
 		if (aname == "") {
@@ -2221,7 +2221,7 @@ class EditorExportAndroid : public EditorExportPlatform {
 	String get_package_name(const String &p_package) {
 
 		String pname = p_package;
-		String basename = GlobalConfig::get_singleton()->get("application/config/name");
+		String basename = ProjectSettings::get_singleton()->get("application/config/name");
 		basename = basename.to_lower();
 
 		String name;
@@ -2537,6 +2537,10 @@ class EditorExportAndroid : public EditorExportPlatform {
 							}*/
 						}
 
+						if (tname == "uses-feature" && /*nspace=="android" &&*/ attrname == "glEsVersion") {
+							print_line("version number: " + itos(decode_uint32(&p_manifest[iofs + 16])));
+						}
+
 						if (tname == "uses-permission" && /*nspace=="android" &&*/ attrname == "name") {
 
 							if (value.begins_with("godot.custom")) {
@@ -2751,8 +2755,8 @@ class EditorExportAndroid : public EditorExportPlatform {
 
 					String lang = str.substr(str.find_last("-") + 1, str.length()).replace("-", "_");
 					String prop = "application/config/name_" + lang;
-					if (GlobalConfig::get_singleton()->has(prop)) {
-						str = GlobalConfig::get_singleton()->get(prop);
+					if (ProjectSettings::get_singleton()->has(prop)) {
+						str = ProjectSettings::get_singleton()->get(prop);
 					} else {
 						str = get_project_name(package_name);
 					}
@@ -2831,6 +2835,8 @@ public:
 
 	virtual void get_export_options(List<ExportOption> *r_options) {
 
+		r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1));
+		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
@@ -2843,7 +2849,6 @@ public:
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architecture/arm"), true));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architecture/x86"), false));
-		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/use_32_bits_view"), true));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "screen/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait"), 0));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true));
@@ -2875,6 +2880,11 @@ public:
 	virtual String get_name() const {
 		return "Android";
 	}
+
+	virtual String get_os_name() const {
+		return "Android";
+	}
+
 	virtual Ref<Texture> get_logo() const {
 		return logo;
 	}
@@ -3219,7 +3229,7 @@ public:
 
 				if (!found) {
 
-					String appicon = GlobalConfig::get_singleton()->get("application/config/icon");
+					String appicon = ProjectSettings::get_singleton()->get("application/config/icon");
 					if (appicon != "" && appicon.ends_with(".png")) {
 						FileAccess *f = FileAccess::open(appicon, FileAccess::READ);
 						if (f) {
@@ -3527,6 +3537,12 @@ public:
 		return OK;
 	}
 
+	virtual void get_platform_features(List<String> *r_features) {
+
+		r_features->push_back("mobile");
+		r_features->push_back("Android");
+	}
+
 	EditorExportAndroid() {
 
 		Ref<Image> img = memnew(Image(_android_logo));

+ 2 - 2
platform/android/globals/global_defaults.cpp

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "global_defaults.h"
-#include "global_config.h"
+#include "project_settings.h"
 
 void register_android_global_defaults() {
 
@@ -37,6 +37,6 @@ void register_android_global_defaults() {
 	GLOBAL_DEF("display.Android/driver","GLES2");
 	//GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
 
-	GlobalConfig::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES2"));
+	ProjectSettings::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES2"));
 	*/
 }

+ 4 - 4
platform/android/godot_android.cpp

@@ -36,7 +36,7 @@
 #include <GLES2/gl2.h>
 
 #include "file_access_android.h"
-#include "global_config.h"
+#include "project_settings.h"
 #include "main/main.h"
 #include "os_android.h"
 #include <android/log.h>
@@ -623,7 +623,7 @@ static void engine_handle_cmd(struct android_app *app, int32_t cmd) {
 #else
 					Error err = Main::setup("apk", 0, NULL);
 
-					String modules = GlobalConfig::get_singleton()->get("android/modules");
+					String modules = ProjectSettings::get_singleton()->get("android/modules");
 					Vector<String> mods = modules.split(",", false);
 					mods.push_back("GodotOS");
 					__android_log_print(ANDROID_LOG_INFO, "godot", "mod count: %i", mods.size());
@@ -859,7 +859,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerSingleton(JNIEnv
 	s->set_instance(env->NewGlobalRef(p_object));
 	jni_singletons[singname] = s;
 
-	GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton(singname, s));
+	ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton(singname, s));
 }
 
 static Variant::Type get_jni_type(const String &p_type) {
@@ -926,7 +926,7 @@ JNIEXPORT jstring JNICALL Java_org_godotengine_godot_Godot_getGlobal(JNIEnv *env
 
 	String js = env->GetStringUTFChars(path, NULL);
 
-	return env->NewStringUTF(GlobalConfig::get_singleton()->get(js).operator String().utf8().get_data());
+	return env->NewStringUTF(ProjectSettings::get_singleton()->get(js).operator String().utf8().get_data());
 }
 
 JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) {

Vissa filer visades inte eftersom för många filer har ändrats