Beispiel #1
0
Error DirAccessWindows::make_dir(String p_dir) {

	GLOBAL_LOCK_FUNCTION

	p_dir = fix_path(p_dir);
	if (p_dir.is_rel_path())
		p_dir = current_dir.plus_file(p_dir);

	p_dir = p_dir.replace("/", "\\");

	bool success;
	int err;

	p_dir = "\\\\?\\" + p_dir; //done according to
	// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx

	success = CreateDirectoryW(p_dir.c_str(), NULL);
	err = GetLastError();

	if (success) {
		return OK;
	};

	if (err == ERROR_ALREADY_EXISTS || err == ERROR_ACCESS_DENIED) {
		return ERR_ALREADY_EXISTS;
	};

	return ERR_CANT_CREATE;
}
Beispiel #2
0
Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {


	String local_path;
	if (p_path.is_rel_path())
		local_path="res://"+p_path;
	else
		local_path = Globals::get_singleton()->localize_path(p_path);

	String remapped_path = PathRemap::get_singleton()->get_remap(local_path);

	String extension=remapped_path.extension();

	for (int i=0;i<loader_count;i++) {

		if (!loader[i]->recognize(extension))
			continue;
		//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
		//	continue;

		return loader[i]->rename_dependencies(p_path,p_map);

	}

	return OK; // ??

}
Beispiel #3
0
Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {

	String path = p_path;

	if (FileAccess::exists(path) && path.is_rel_path()) {
		// dlopen expects a slash, in this case a leading ./ for it to be interpreted as a relative path,
		//  otherwise it will end up searching various system directories for the lib instead and finally failing.
		path = "./" + path;
	}

	if (!FileAccess::exists(path)) {
		//this code exists so gdnative can load .so files from within the executable path
		path = get_executable_path().get_base_dir().plus_file(p_path.get_file());
	}

	if (!FileAccess::exists(path)) {
		//this code exists so gdnative can load .so files from a standard unix location
		path = get_executable_path().get_base_dir().plus_file("../lib").plus_file(p_path.get_file());
	}

	p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
	if (!p_library_handle) {
		ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
		ERR_FAIL_V(ERR_CANT_OPEN);
	}
	return OK;
}
Beispiel #4
0
bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = ProjectSettings::get_singleton()->localize_path(p_path);

	if (ResourceCache::has(local_path)) {

		return true; // If cached, it probably exists
	}

	bool xl_remapped = false;
	String path = _path_remap(local_path, &xl_remapped);

	// Try all loaders and pick the first match for the type hint
	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(path, p_type_hint)) {
			continue;
		}

		if (loader[i]->exists(path))
			return true;
	}

	return false;
}
Beispiel #5
0
bool DirAccessJAndroid::dir_exists(String p_dir) {

	JNIEnv *env = ThreadAndroid::get_env();

	String sd;

	if (current_dir == "")
		sd = p_dir;
	else {
		if (p_dir.is_rel_path())
			sd = current_dir.plus_file(p_dir);
		else
			sd = fix_path(p_dir);
	}

	String path = sd.simplify_path();

	if (path.begins_with("/"))
		path = path.substr(1, path.length());
	else if (path.begins_with("res://"))
		path = path.substr(6, path.length());

	jstring js = env->NewStringUTF(path.utf8().get_data());
	int res = env->CallIntMethod(io, _dir_open, js);
	env->DeleteLocalRef(js);
	if (res <= 0)
		return false;

	env->CallVoidMethod(io, _dir_close, res);

	return true;
}
Beispiel #6
0
Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) {



	String local_path;
	if (p_path.is_rel_path())
		local_path="res://"+p_path;
	else
		local_path = Globals::get_singleton()->localize_path(p_path);

	String extension=p_path.extension();
	Ref<ResourceImportMetadata> ret;

	for (int i=0;i<loader_count;i++) {

		if (!loader[i]->recognize(extension))
			continue;

		Error err = loader[i]->load_import_metadata(local_path,ret);
		if (err==OK)
			break;
	}


	return ret;

}
Beispiel #7
0
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {

	if (r_error)
		*r_error = ERR_CANT_OPEN;

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = GlobalConfig::get_singleton()->localize_path(p_path);

	ERR_FAIL_COND_V(local_path == "", RES());

	if (!p_no_cache && ResourceCache::has(local_path)) {

		if (OS::get_singleton()->is_stdout_verbose())
			print_line("load resource: " + local_path + " (cached)");

		return RES(ResourceCache::get(local_path));
	}

	if (OS::get_singleton()->is_stdout_verbose())
		print_line("load resource: " + local_path);
	bool found = false;

	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(local_path, p_type_hint)) {
			print_line("path not recognized");
			continue;
		}
		found = true;
		RES res = loader[i]->load(local_path, local_path, r_error);
		if (res.is_null()) {
			continue;
		}
		if (!p_no_cache)
			res->set_path(local_path);
#ifdef TOOLS_ENABLED

		res->set_edited(false);
		if (timestamp_on_load) {
			uint64_t mt = FileAccess::get_modified_time(local_path);
			//printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
			res->set_last_modified_time(mt);
		}
#endif

		return res;
	}

	if (found) {
		ERR_EXPLAIN("Failed loading resource: " + p_path);
	} else {
		ERR_EXPLAIN("No loader found for resource: " + p_path);
	}
	ERR_FAIL_V(RES());
	return RES();
}
String EditorImportPlugin::expand_source_path(const String& p_path) {

	if (p_path.is_rel_path()) {
		return Globals::get_singleton()->get_resource_path().plus_file(p_path).simplify_path();
	} else {
		return p_path;
	}
}
Beispiel #9
0
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache,Error *r_error) {


	if (r_error)
		*r_error=ERR_CANT_OPEN;

	String local_path;
	if (p_path.is_rel_path())
		local_path="res://"+p_path;
	else
		local_path = Globals::get_singleton()->localize_path(p_path);

	local_path=find_complete_path(local_path,p_type_hint);
	ERR_FAIL_COND_V(local_path=="",Ref<ResourceInteractiveLoader>());



	if (!p_no_cache && ResourceCache::has(local_path)) {

		if (OS::get_singleton()->is_stdout_verbose())
			print_line("load resource: "+local_path+" (cached)");

		return RES( ResourceCache::get(local_path ) );
	}

	if (OS::get_singleton()->is_stdout_verbose())
		print_line("load resource: ");

	String remapped_path = PathRemap::get_singleton()->get_remap(local_path);

	String extension=remapped_path.extension();
	bool found=false;

	for (int i=0;i<loader_count;i++) {

		if (!loader[i]->recognize(extension))
			continue;
		if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
			continue;
		found=true;
		Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path,r_error);
		if (ril.is_null())
			continue;
		if (!p_no_cache)
			ril->set_local_path(local_path);

		return ril;
	}

	if (found) {
		ERR_EXPLAIN("Failed loading resource: "+p_path);
	} else {
		ERR_EXPLAIN("No loader found for resource: "+p_path);
	}
	ERR_FAIL_V(Ref<ResourceInteractiveLoader>());
	return Ref<ResourceInteractiveLoader>();

}
Beispiel #10
0
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {

	if (r_error)
		*r_error = ERR_CANT_OPEN;

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = ProjectSettings::get_singleton()->localize_path(p_path);

	bool xl_remapped = false;
	String path = _path_remap(local_path, &xl_remapped);

	ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>());

	if (!p_no_cache && ResourceCache::has(path)) {

		if (OS::get_singleton()->is_stdout_verbose())
			print_line("load resource: " + path + " (cached)");

		Ref<Resource> res_cached = ResourceCache::get(path);
		Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));

		ril->resource = res_cached;
		return ril;
	}

	if (OS::get_singleton()->is_stdout_verbose())
		print_line("load resource: ");

	bool found = false;

	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(path, p_type_hint))
			continue;
		found = true;
		Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error);
		if (ril.is_null())
			continue;
		if (!p_no_cache)
			ril->set_local_path(local_path);
		if (xl_remapped)
			ril->set_translation_remapped(true);

		return ril;
	}

	if (found) {
		ERR_EXPLAIN("Failed loading resource: " + path);
	} else {
		ERR_EXPLAIN("No loader found for resource: " + path);
	}
	ERR_FAIL_V(Ref<ResourceInteractiveLoader>());
	return Ref<ResourceInteractiveLoader>();
}
Beispiel #11
0
Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags) {
	List<String> dirs;

	String curdir = get_current_dir();
	list_dir_begin();
	String n = get_next();
	while (n != String()) {

		if (n != "." && n != "..") {

			if (current_is_dir())
				dirs.push_back(n);
			else {
				String rel_path = n;
				if (!n.is_rel_path()) {
					list_dir_end();
					return ERR_BUG;
				}
				Error err = copy(get_current_dir() + "/" + n, p_to + rel_path, p_chmod_flags);
				if (err) {
					list_dir_end();
					return err;
				}
			}
		}

		n = get_next();
	}

	list_dir_end();

	for (List<String>::Element *E = dirs.front(); E; E = E->next()) {
		String rel_path = E->get();
		String target_dir = p_to + rel_path;
		if (!p_target_da->dir_exists(target_dir)) {
			Error err = p_target_da->make_dir(target_dir);
			ERR_FAIL_COND_V(err, err);
		}

		Error err = change_dir(E->get());
		ERR_FAIL_COND_V(err, err);
		err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags);
		if (err) {
			change_dir("..");
			ERR_PRINT("Failed to copy recursively");
			return err;
		}
		err = change_dir("..");
		if (err) {
			ERR_PRINT("Failed to go back");
			return err;
		}
	}

	return OK;
}
Beispiel #12
0
String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {

	String local_path;
	if (p_path.is_rel_path())
		local_path="res://"+p_path;
	else
		local_path = Globals::get_singleton()->localize_path(p_path);

	return find_complete_path(local_path,p_type);

}
Beispiel #13
0
Error DirAccess::make_dir_recursive(String p_dir) {

	if (p_dir.length() < 1) {
		return OK;
	};

	String full_dir;

	if (p_dir.is_rel_path()) {
		//append current		
		full_dir=get_current_dir().plus_file(p_dir);

	} else {
		full_dir=p_dir;
	}

	full_dir=full_dir.replace("\\","/");

	//int slices = full_dir.get_slice_count("/");

	String base;

	if (full_dir.begins_with("res://"))
		base="res://";
	else if (full_dir.begins_with("user://"))
		base="user://";
	else if (full_dir.begins_with("/"))
		base="/";
	else if (full_dir.find(":/")!=-1) {
		base=full_dir.substr(0,full_dir.find(":/")+2);
	} else {
		ERR_FAIL_V(ERR_INVALID_PARAMETER);
	}

	full_dir=full_dir.replace_first(base,"").simplify_path();

	Vector<String> subdirs=full_dir.split("/");

	String curpath=base;
	for(int i=0;i<subdirs.size();i++) {

		curpath=curpath.plus_file(subdirs[i]);
		Error err = make_dir(curpath);
		if (err != OK && err != ERR_ALREADY_EXISTS) {

			ERR_FAIL_V(err);
		}
	}

	return OK;
}
Beispiel #14
0
String ResourceLoader::get_resource_type(const String &p_path) {

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = ProjectSettings::get_singleton()->localize_path(p_path);

	for (int i = 0; i < loader_count; i++) {

		String result = loader[i]->get_resource_type(local_path);
		if (result != "")
			return result;
	}

	return "";
}
Beispiel #15
0
Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str){

	VariantParser::Token token;
	VariantParser::get_token(p_stream,token,line,r_err_str);
	if (token.type!=VariantParser::TK_NUMBER) {
		r_err_str="Expected number (sub-resource index)";
		return ERR_PARSE_ERROR;
	}

	int id = token.value;

	if (!ignore_resource_parsing) {

		if (!ext_resources.has(id)) {
			r_err_str="Can't load cached ext-resource #"+itos(id);
			return ERR_PARSE_ERROR;
		}

		String path = ext_resources[id].path;
		String type = ext_resources[id].type;

		if (path.find("://")==-1 && path.is_rel_path()) {
			// path is relative to file being loaded, so convert to a resource path
			path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));

		}

		r_res=ResourceLoader::load(path,type);

		if (r_res.is_null()) {
			WARN_PRINT(String("Couldn't load external resource: "+path).utf8().get_data());
		}
	} else {
		r_res=RES();
	}

	VariantParser::get_token(p_stream,token,line,r_err_str);
	if (token.type!=VariantParser::TK_PARENTHESIS_CLOSE) {
		r_err_str="Expected ')'";
		return ERR_PARSE_ERROR;
	}


	return OK;
}
Beispiel #16
0
Error DirAccessFlash::change_dir(String p_dir) {

	if (p_dir==".")
		return OK;


	if (p_dir.is_rel_path())
		current_dir+="/"+p_dir;
	else
		current_dir=fix_path(p_dir);

	current_dir=current_dir.simplify_path();
	if (current_dir.length()>1 && current_dir.ends_with("/") && !current_dir.ends_with("//"))
		current_dir=current_dir.substr(0,current_dir.length()-1);

	return OK;

};
Beispiel #17
0
void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = GlobalConfig::get_singleton()->localize_path(p_path);

	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(local_path))
			continue;
		/*
		if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
			continue;
		*/

		loader[i]->get_dependencies(local_path, p_dependencies, p_add_types);
	}
}
Beispiel #18
0
String ResourceLoader::get_resource_type(const String &p_path) {

	String local_path;
	if (p_path.is_rel_path())
		local_path="res://"+p_path;
	else
		local_path = Globals::get_singleton()->localize_path(p_path);

	String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
	String extension=remapped_path.extension();

	for (int i=0;i<loader_count;i++) {

		String result = loader[i]->get_resource_type(local_path);
		if (result!="")
			return result;
	}

	return "";

}
Beispiel #19
0
Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = GlobalConfig::get_singleton()->localize_path(p_path);

	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(local_path))
			continue;
		/*
		if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
			continue;
		*/

		return loader[i]->rename_dependencies(local_path, p_map);
	}

	return OK; // ??
}
Beispiel #20
0
String ResourceLoader::get_import_group_file(const String &p_path) {
	String path = _path_remap(p_path);

	String local_path;
	if (path.is_rel_path())
		local_path = "res://" + path;
	else
		local_path = ProjectSettings::get_singleton()->localize_path(path);

	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(local_path))
			continue;
		/*
		if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
			continue;
		*/

		return loader[i]->get_import_group_file(p_path);
	}

	return String(); //not found
}
Beispiel #21
0
void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {


	String local_path;
	if (p_path.is_rel_path())
		local_path="res://"+p_path;
	else
		local_path = Globals::get_singleton()->localize_path(p_path);

	String remapped_path = PathRemap::get_singleton()->get_remap(local_path);

	String extension=remapped_path.extension();

	for (int i=0;i<loader_count;i++) {

		if (!loader[i]->recognize(extension))
			continue;
		//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
		//	continue;

		loader[i]->get_dependencies(remapped_path,p_dependencies,p_add_types);

	}
}
Beispiel #22
0
static Ref<Reference> _get_parent_class(GDCompletionContext& context) {



	if (context._class->extends_used) {
		//do inheritance
		String path = context._class->extends_file;

		Ref<GDScript> script;
		Ref<GDNativeClass> native;

		if (path!="") {
			//path (and optionally subclasses)

			if (path.is_rel_path()) {

				path=context.base_path.plus_file(path);
			}
			script = ResourceLoader::load(path);
			if (script.is_null()) {
				return REF();
			}
			if (script->is_valid()) {

				return REF();
			}
			//print_line("EXTENDS PATH: "+path+" script is "+itos(script.is_valid())+" indices is "+itos(script->member_indices.size())+" valid? "+itos(script->valid));

			if (context._class->extends_class.size()) {

				for(int i=0;i<context._class->extends_class.size();i++) {

					String sub = context._class->extends_class[i];
					if (script->get_subclasses().has(sub)) {

						script=script->get_subclasses()[sub];
					} else {

						return REF();
					}
				}
			}

			if (script.is_valid())
				return script;

		} else {

			if (context._class->extends_class.size()==0) {
				ERR_PRINT("BUG");
				return REF();
			}

			String base=context._class->extends_class[0];
			const GDParser::ClassNode *p = context._class->owner;
			Ref<GDScript> base_class;
#if 0
			while(p) {

				if (p->subclasses.has(base)) {

					base_class=p->subclasses[base];
					break;
				}
				p=p->_owner;
			}
#endif
			if (base_class.is_valid()) {
#if 0
				for(int i=1;i<context._class->extends_class.size();i++) {

					String subclass=context._class->extends_class[i];

					if (base_class->subclasses.has(subclass)) {

						base_class=base_class->subclasses[subclass];
					} else {

						print_line("Could not find subclass: "+subclass);
						return _get_type_from_class(context); //fail please
					}
				}

				script=base_class;
#endif

			} else {

				if (context._class->extends_class.size()>1) {

					return REF();


				}
				//if not found, try engine classes
				if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) {

					return REF();
				}

				int base_idx = GDScriptLanguage::get_singleton()->get_global_map()[base];
				native = GDScriptLanguage::get_singleton()->get_global_array()[base_idx];
				if (!native.is_valid()) {

					print_line("Global not a class: '"+base+"'");

				}
				return native;
			}


		}

	}

	return Ref<Reference>();
}
Beispiel #23
0
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {

	if (r_error)
		*r_error = ERR_CANT_OPEN;

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = ProjectSettings::get_singleton()->localize_path(p_path);

	if (!p_no_cache) {

		bool success = _add_to_loading_map(local_path);
		if (!success) {
			ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
			ERR_FAIL_V(RES());
		}

		if (ResourceCache::has(local_path)) {

			print_verbose("Loading resource: " + local_path + " (cached)");
			Ref<Resource> res_cached = ResourceCache::get(local_path);
			Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));

			ril->resource = res_cached;
			ril->path_loading = local_path;
			ril->path_loading_thread = Thread::get_caller_id();
			return ril;
		}
	}

	bool xl_remapped = false;
	String path = _path_remap(local_path, &xl_remapped);
	if (path == "") {
		if (!p_no_cache) {
			_remove_from_loading_map(local_path);
		}
		ERR_EXPLAIN("Remapping '" + local_path + "'failed.");
		ERR_FAIL_V(RES());
	}

	print_verbose("Loading resource: " + path);

	bool found = false;
	for (int i = 0; i < loader_count; i++) {

		if (!loader[i]->recognize_path(path, p_type_hint))
			continue;
		found = true;
		Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error);
		if (ril.is_null())
			continue;
		if (!p_no_cache) {
			ril->set_local_path(local_path);
			ril->path_loading = local_path;
			ril->path_loading_thread = Thread::get_caller_id();
		}

		if (xl_remapped)
			ril->set_translation_remapped(true);

		return ril;
	}

	if (!p_no_cache) {
		_remove_from_loading_map(local_path);
	}

	if (found) {
		ERR_EXPLAIN("Failed loading resource: " + path);
	} else {
		ERR_EXPLAIN("No loader found for resource: " + path);
	}
	ERR_FAIL_V(Ref<ResourceInteractiveLoader>());
	return Ref<ResourceInteractiveLoader>();
}
Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v)  {


	uint32_t type = f->get_32();
	print_bl("find property of type: "+itos(type));


	switch(type) {

		case VARIANT_NIL: {

			r_v=Variant();
		} break;
		case VARIANT_BOOL: {

			r_v=bool(f->get_32());
		} break;
		case VARIANT_INT: {

			r_v=int(f->get_32());
		} break;
		case VARIANT_REAL: {

			r_v=f->get_real();
		} break;
		case VARIANT_STRING: {

			r_v=get_unicode_string();
		} break;
		case VARIANT_VECTOR2: {

			Vector2 v;
			v.x=f->get_real();
			v.y=f->get_real();
			r_v=v;

		} break;
		case VARIANT_RECT2: {

			Rect2 v;
			v.pos.x=f->get_real();
			v.pos.y=f->get_real();
			v.size.x=f->get_real();
			v.size.y=f->get_real();
			r_v=v;

		} break;
		case VARIANT_VECTOR3: {

			Vector3 v;
			v.x=f->get_real();
			v.y=f->get_real();
			v.z=f->get_real();
			r_v=v;
		} break;
		case VARIANT_PLANE: {

			Plane v;
			v.normal.x=f->get_real();
			v.normal.y=f->get_real();
			v.normal.z=f->get_real();
			v.d=f->get_real();
			r_v=v;
		} break;
		case VARIANT_QUAT: {
			Quat v;
			v.x=f->get_real();
			v.y=f->get_real();
			v.z=f->get_real();
			v.w=f->get_real();
			r_v=v;

		} break;
		case VARIANT_AABB: {

			AABB v;
			v.pos.x=f->get_real();
			v.pos.y=f->get_real();
			v.pos.z=f->get_real();
			v.size.x=f->get_real();
			v.size.y=f->get_real();
			v.size.z=f->get_real();
			r_v=v;

		} break;
		case VARIANT_MATRIX32: {

			Matrix32 v;
			v.elements[0].x=f->get_real();
			v.elements[0].y=f->get_real();
			v.elements[1].x=f->get_real();
			v.elements[1].y=f->get_real();
			v.elements[2].x=f->get_real();
			v.elements[2].y=f->get_real();
			r_v=v;

		} break;
		case VARIANT_MATRIX3: {

			Matrix3 v;
			v.elements[0].x=f->get_real();
			v.elements[0].y=f->get_real();
			v.elements[0].z=f->get_real();
			v.elements[1].x=f->get_real();
			v.elements[1].y=f->get_real();
			v.elements[1].z=f->get_real();
			v.elements[2].x=f->get_real();
			v.elements[2].y=f->get_real();
			v.elements[2].z=f->get_real();
			r_v=v;

		} break;
		case VARIANT_TRANSFORM: {

			Transform v;
			v.basis.elements[0].x=f->get_real();
			v.basis.elements[0].y=f->get_real();
			v.basis.elements[0].z=f->get_real();
			v.basis.elements[1].x=f->get_real();
			v.basis.elements[1].y=f->get_real();
			v.basis.elements[1].z=f->get_real();
			v.basis.elements[2].x=f->get_real();
			v.basis.elements[2].y=f->get_real();
			v.basis.elements[2].z=f->get_real();
			v.origin.x=f->get_real();
			v.origin.y=f->get_real();
			v.origin.z=f->get_real();
			r_v=v;
		} break;
		case VARIANT_COLOR: {

			Color v;
			v.r=f->get_real();
			v.g=f->get_real();
			v.b=f->get_real();
			v.a=f->get_real();
			r_v=v;

		} break;
		case VARIANT_IMAGE: {


			uint32_t encoding = f->get_32();
			if (encoding==IMAGE_ENCODING_EMPTY) {
				r_v=Variant();
				break;
			} else if (encoding==IMAGE_ENCODING_RAW) {
				uint32_t width = f->get_32();
				uint32_t height = f->get_32();
				uint32_t mipmaps = f->get_32();
				uint32_t format = f->get_32();
				Image::Format fmt;
				switch(format) {

					case IMAGE_FORMAT_GRAYSCALE: { fmt=Image::FORMAT_GRAYSCALE; } break;
					case IMAGE_FORMAT_INTENSITY: { fmt=Image::FORMAT_INTENSITY; } break;
					case IMAGE_FORMAT_GRAYSCALE_ALPHA: { fmt=Image::FORMAT_GRAYSCALE_ALPHA; } break;
					case IMAGE_FORMAT_RGB: { fmt=Image::FORMAT_RGB; } break;
					case IMAGE_FORMAT_RGBA: { fmt=Image::FORMAT_RGBA; } break;
					case IMAGE_FORMAT_INDEXED: { fmt=Image::FORMAT_INDEXED; } break;
					case IMAGE_FORMAT_INDEXED_ALPHA: { fmt=Image::FORMAT_INDEXED_ALPHA; } break;
					case IMAGE_FORMAT_BC1: { fmt=Image::FORMAT_BC1; } break;
					case IMAGE_FORMAT_BC2: { fmt=Image::FORMAT_BC2; } break;
					case IMAGE_FORMAT_BC3: { fmt=Image::FORMAT_BC3; } break;
					case IMAGE_FORMAT_BC4: { fmt=Image::FORMAT_BC4; } break;
					case IMAGE_FORMAT_BC5: { fmt=Image::FORMAT_BC5; } break;
					case IMAGE_FORMAT_PVRTC2: { fmt=Image::FORMAT_PVRTC2; } break;
					case IMAGE_FORMAT_PVRTC2_ALPHA: { fmt=Image::FORMAT_PVRTC2_ALPHA; } break;
					case IMAGE_FORMAT_PVRTC4: { fmt=Image::FORMAT_PVRTC4; } break;
					case IMAGE_FORMAT_PVRTC4_ALPHA: { fmt=Image::FORMAT_PVRTC4_ALPHA; } break;
					case IMAGE_FORMAT_ETC: { fmt=Image::FORMAT_ETC; } break;
					case IMAGE_FORMAT_CUSTOM: { fmt=Image::FORMAT_CUSTOM; } break;
					default: {

						ERR_FAIL_V(ERR_FILE_CORRUPT);
					}

				}


				uint32_t datalen = f->get_32();

				DVector<uint8_t> imgdata;
				imgdata.resize(datalen);
				DVector<uint8_t>::Write w = imgdata.write();
				f->get_buffer(w.ptr(),datalen);
				_advance_padding(datalen);
				w=DVector<uint8_t>::Write();

				r_v=Image(width,height,mipmaps,fmt,imgdata);

			} else {
				//compressed
				DVector<uint8_t> data;
				data.resize(f->get_32());
				DVector<uint8_t>::Write w = data.write();
				f->get_buffer(w.ptr(),data.size());
				w = DVector<uint8_t>::Write();

				Image img;

				if (encoding==IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) {

					img = Image::lossy_unpacker(data);
				} else if (encoding==IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) {

					img = Image::lossless_unpacker(data);
				}
				_advance_padding(data.size());


				r_v=img;

			}

		} break;
		case VARIANT_NODE_PATH: {

			Vector<StringName> names;
			Vector<StringName> subnames;
			StringName property;
			bool absolute;

			int name_count = f->get_16();
			uint32_t subname_count = f->get_16();
			absolute=subname_count&0x8000;
			subname_count&=0x7FFF;


			for(int i=0;i<name_count;i++)
				names.push_back(string_map[f->get_32()]);
			for(uint32_t i=0;i<subname_count;i++)
				subnames.push_back(string_map[f->get_32()]);
			property=string_map[f->get_32()];

			NodePath np = NodePath(names,subnames,absolute,property);
			//print_line("got path: "+String(np));

			r_v=np;

		} break;
		case VARIANT_RID: {

			r_v=f->get_32();
		} break;
		case VARIANT_OBJECT: {

			uint32_t type=f->get_32();

			switch(type) {

				case OBJECT_EMPTY: {
					//do none

				} break;
				case OBJECT_INTERNAL_RESOURCE: {
					uint32_t index=f->get_32();
					String path = res_path+"::"+itos(index);
					RES res = ResourceLoader::load(path);
					if (res.is_null()) {
						WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
					}
					r_v=res;

				} break;
				case OBJECT_EXTERNAL_RESOURCE: {

					String type = get_unicode_string();
					String path = get_unicode_string();

					if (path.find("://")==-1 && path.is_rel_path()) {
						// path is relative to file being loaded, so convert to a resource path
						path=Globals::get_singleton()->localize_path(res_path.get_base_dir()+"/"+path);

					}

					RES res=ResourceLoader::load(path,type);

					if (res.is_null()) {
						WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
					}
					r_v=res;

				} break;
				default: {

					ERR_FAIL_V(ERR_FILE_CORRUPT);
				} break;
			}

		} break;
		case VARIANT_INPUT_EVENT: {

		} break;
		case VARIANT_DICTIONARY: {

            uint32_t len=f->get_32();
            Dictionary d(len&0x80000000); //last bit means shared
            len&=0x7FFFFFFF;
            for(uint32_t i=0;i<len;i++) {
				Variant key;
				Error err = parse_variant(key);
				ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
				Variant value;
				err = parse_variant(value);
				ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
				d[key]=value;
			}
			r_v=d;
		} break;
		case VARIANT_ARRAY: {

            uint32_t len=f->get_32();
            Array a(len&0x80000000); //last bit means shared
            len&=0x7FFFFFFF;
			a.resize(len);
            for(uint32_t i=0;i<len;i++) {
				Variant val;
				Error err = parse_variant(val);
				ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
				a[i]=val;
			}
			r_v=a;

		} break;
		case VARIANT_RAW_ARRAY: {

			uint32_t len = f->get_32();

			DVector<uint8_t> array;
			array.resize(len);
			DVector<uint8_t>::Write w = array.write();
			f->get_buffer(w.ptr(),len);
			_advance_padding(len);
			w=DVector<uint8_t>::Write();
			r_v=array;

		} break;
		case VARIANT_INT_ARRAY: {

			uint32_t len = f->get_32();

			DVector<int> array;
			array.resize(len);
			DVector<int>::Write w = array.write();
			f->get_buffer((uint8_t*)w.ptr(),len*4);
#ifdef BIG_ENDIAN_ENABLED
			{
				uint32_t *ptr=(uint32_t*)w.ptr();
				for(int i=0;i<len;i++) {

					ptr[i]=BSWAP32(ptr[i]);
				}
			}

#endif
			w=DVector<int>::Write();
			r_v=array;
		} break;
		case VARIANT_REAL_ARRAY: {

			uint32_t len = f->get_32();

			DVector<real_t> array;
			array.resize(len);
			DVector<real_t>::Write w = array.write();
			f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t));
#ifdef BIG_ENDIAN_ENABLED
			{
				uint32_t *ptr=(uint32_t*)w.ptr();
				for(int i=0;i<len;i++) {

					ptr[i]=BSWAP32(ptr[i]);
				}
			}

#endif

			w=DVector<real_t>::Write();
			r_v=array;
		} break;
		case VARIANT_STRING_ARRAY: {

			uint32_t len = f->get_32();
			DVector<String> array;
			array.resize(len);
			DVector<String>::Write w = array.write();
			for(uint32_t i=0;i<len;i++)
				w[i]=get_unicode_string();
			w=DVector<String>::Write();
			r_v=array;


		} break;
		case VARIANT_VECTOR2_ARRAY: {

			uint32_t len = f->get_32();

			DVector<Vector2> array;
			array.resize(len);
			DVector<Vector2>::Write w = array.write();
			if (sizeof(Vector2)==8) {
				f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*2);
#ifdef BIG_ENDIAN_ENABLED
			{
				uint32_t *ptr=(uint32_t*)w.ptr();
				for(int i=0;i<len*2;i++) {

					ptr[i]=BSWAP32(ptr[i]);
				}
			}

#endif

			} else {
				ERR_EXPLAIN("Vector2 size is NOT 8!");
				ERR_FAIL_V(ERR_UNAVAILABLE);
			}
			w=DVector<Vector2>::Write();
			r_v=array;

		} break;
		case VARIANT_VECTOR3_ARRAY: {

			uint32_t len = f->get_32();

			DVector<Vector3> array;
			array.resize(len);
			DVector<Vector3>::Write w = array.write();
			if (sizeof(Vector3)==12) {
				f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*3);
#ifdef BIG_ENDIAN_ENABLED
				{
					uint32_t *ptr=(uint32_t*)w.ptr();
					for(int i=0;i<len*3;i++) {

						ptr[i]=BSWAP32(ptr[i]);
					}
				}

#endif

			} else {
				ERR_EXPLAIN("Vector3 size is NOT 12!");
				ERR_FAIL_V(ERR_UNAVAILABLE);
			}
			w=DVector<Vector3>::Write();
			r_v=array;

		} break;
		case VARIANT_COLOR_ARRAY: {

			uint32_t len = f->get_32();

			DVector<Color> array;
			array.resize(len);
			DVector<Color>::Write w = array.write();
			if (sizeof(Color)==16) {
				f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*4);
#ifdef BIG_ENDIAN_ENABLED
			{
				uint32_t *ptr=(uint32_t*)w.ptr();
				for(int i=0;i<len*4;i++) {

					ptr[i]=BSWAP32(ptr[i]);
				}
			}

#endif

			} else {
				ERR_EXPLAIN("Color size is NOT 16!");
				ERR_FAIL_V(ERR_UNAVAILABLE);
			}
			w=DVector<Color>::Write();
			r_v=array;
		} break;

		default: {
			ERR_FAIL_V(ERR_FILE_CORRUPT);
		} break;
	}



	return OK; //never reach anyway

}
Beispiel #25
0
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {

	if (r_error)
		*r_error = ERR_CANT_OPEN;

	String local_path;
	if (p_path.is_rel_path())
		local_path = "res://" + p_path;
	else
		local_path = ProjectSettings::get_singleton()->localize_path(p_path);

	if (!p_no_cache) {

		{
			bool success = _add_to_loading_map(local_path);
			if (!success) {
				ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
				ERR_FAIL_V(RES());
			}
		}

		//lock first if possible
		if (ResourceCache::lock) {
			ResourceCache::lock->read_lock();
		}

		//get ptr
		Resource **rptr = ResourceCache::resources.getptr(local_path);

		if (rptr) {
			RES res(*rptr);
			//it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
			if (res.is_valid()) {
				//referencing is fine
				if (r_error)
					*r_error = OK;
				if (ResourceCache::lock) {
					ResourceCache::lock->read_unlock();
				}
				_remove_from_loading_map(local_path);
				return res;
			}
		}
		if (ResourceCache::lock) {
			ResourceCache::lock->read_unlock();
		}
	}

	bool xl_remapped = false;
	String path = _path_remap(local_path, &xl_remapped);

	if (path == "") {
		if (!p_no_cache) {
			_remove_from_loading_map(local_path);
		}
		ERR_EXPLAIN("Remapping '" + local_path + "'failed.");
		ERR_FAIL_V(RES());
	}

	print_verbose("Loading resource: " + path);
	RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error);

	if (res.is_null()) {
		if (!p_no_cache) {
			_remove_from_loading_map(local_path);
		}
		return RES();
	}
	if (!p_no_cache)
		res->set_path(local_path);

	if (xl_remapped)
		res->set_as_translation_remapped(true);

#ifdef TOOLS_ENABLED

	res->set_edited(false);
	if (timestamp_on_load) {
		uint64_t mt = FileAccess::get_modified_time(path);
		//printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
		res->set_last_modified_time(mt);
	}
#endif

	if (!p_no_cache) {
		_remove_from_loading_map(local_path);
	}

	if (_loaded_callback) {
		_loaded_callback(res, p_path);
	}

	return res;
}
Beispiel #26
0
Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDParser::ClassNode *p_class) {


	p_script->native=Ref<GDNativeClass>();
	p_script->base=Ref<GDScript>();
	p_script->_base=NULL;
	p_script->members.clear();
	p_script->constants.clear();
	p_script->member_functions.clear();
	p_script->member_indices.clear();
	p_script->member_info.clear();
	p_script->initializer=NULL;
	p_script->subclasses.clear();
	p_script->_owner=p_owner;
	p_script->tool=p_class->tool;
	p_script->name=p_class->name;


	int index_from=0;

	if (p_class->extends_used) {
		//do inheritance
		String path = p_class->extends_file;

		Ref<GDScript> script;
		Ref<GDNativeClass> native;

		if (path!="") {
			//path (and optionally subclasses)

			if (path.is_rel_path()) {

				String base = p_script->get_path();
				if (base=="" || base.is_rel_path()) {
					_set_error("Could not resolve relative path for parent class: "+path,p_class);
					return ERR_FILE_NOT_FOUND;
				}
				path=base.get_base_dir().plus_file(path);
			}
			script = ResourceLoader::load(path);
			if (script.is_null()) {
				_set_error("Could not load base class: "+path,p_class);
				return ERR_FILE_NOT_FOUND;
			}
			if (!script->valid) {

				_set_error("Script not fully loaded (cyclic preload?): "+path,p_class);
				return ERR_BUSY;
			}
			//print_line("EXTENDS PATH: "+path+" script is "+itos(script.is_valid())+" indices is "+itos(script->member_indices.size())+" valid? "+itos(script->valid));

			if (p_class->extends_class.size()) {

				for(int i=0;i<p_class->extends_class.size();i++) {

					String sub = p_class->extends_class[i];
					if (script->subclasses.has(sub)) {

						script=script->subclasses[sub];
					} else {

						_set_error("Could not find subclass: "+sub,p_class);
						return ERR_FILE_NOT_FOUND;
					}
				}
			}

		} else {

			ERR_FAIL_COND_V(p_class->extends_class.size()==0,ERR_BUG);
			//look around for the subclasses

			String base=p_class->extends_class[0];
			GDScript *p = p_owner;
			Ref<GDScript> base_class;

			while(p) {

				if (p->subclasses.has(base)) {

					base_class=p->subclasses[base];
					break;
				}
				p=p->_owner;
			}

			if (base_class.is_valid()) {

				for(int i=1;i<p_class->extends_class.size();i++) {

					String subclass=p_class->extends_class[i];

					if (base_class->subclasses.has(subclass)) {

						base_class=base_class->subclasses[subclass];
					} else {

						_set_error("Could not find subclass: "+subclass,p_class);
						return ERR_FILE_NOT_FOUND;
					}
				}

				script=base_class;


			} else {

				if (p_class->extends_class.size()>1) {

					_set_error("Invalid inheritance (unknown class+subclasses)",p_class);
					return ERR_FILE_NOT_FOUND;

				}
				//if not found, try engine classes
				if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) {

					_set_error("Unknown class: '"+base+"'",p_class);
					return ERR_FILE_NOT_FOUND;
				}

				int base_idx = GDScriptLanguage::get_singleton()->get_global_map()[base];
				native = GDScriptLanguage::get_singleton()->get_global_array()[base_idx];
				if (!native.is_valid()) {

					_set_error("Global not a class: '"+base+"'",p_class);

					return ERR_FILE_NOT_FOUND;
				}
			}


		}

		if (script.is_valid()) {

			p_script->base=script;
			p_script->_base=p_script->base.ptr();
			p_script->member_indices=script->member_indices;

		} else if (native.is_valid()) {

			p_script->native=native;
		} else {

			_set_error("Could not determine inheritance",p_class);
			return ERR_FILE_NOT_FOUND;
		}


	}


	//print_line("Script: "+p_script->get_path()+" indices: "+itos(p_script->member_indices.size()));


	for(int i=0;i<p_class->variables.size();i++) {

		StringName name = p_class->variables[i].identifier;
		if (p_script->member_indices.has(name)) {
			_set_error("Member '"+name+"' already exists (in current or parent class)",p_class);
			return ERR_ALREADY_EXISTS;
		}

		if (p_class->variables[i]._export.type!=Variant::NIL) {

			p_script->member_info[name]=p_class->variables[i]._export;
#ifdef TOOLS_ENABLED
			if (p_class->variables[i].default_value.get_type()!=Variant::NIL) {

				p_script->member_default_values[name]=p_class->variables[i].default_value;
			}
#endif
		}

		int new_idx = p_script->member_indices.size();
		p_script->member_indices[name]=new_idx;
		p_script->members.insert(name);

	}

	for(int i=0;i<p_class->constant_expressions.size();i++) {

		StringName name = p_class->constant_expressions[i].identifier;
		ERR_CONTINUE( p_class->constant_expressions[i].expression->type!=GDParser::Node::TYPE_CONSTANT );

		GDParser::ConstantNode *constant = static_cast<GDParser::ConstantNode*>(p_class->constant_expressions[i].expression);

		p_script->constants.insert(name,constant->value);
		//p_script->constants[constant->value].make_const();
	}


	//parse sub-classes

	for(int i=0;i<p_class->subclasses.size();i++) {
		StringName name = p_class->subclasses[i]->name;

		Ref<GDScript> subclass = memnew( GDScript );

		Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i]);
		if (err)
			return err;

		p_script->constants.insert(name,subclass); //once parsed, goes to the list of constants
		p_script->subclasses.insert(name,subclass);

	}


	//parse methods

	bool has_initializer=false;
	for(int i=0;i<p_class->functions.size();i++) {

		if (!has_initializer && p_class->functions[i]->name=="_init")
			has_initializer=true;
		Error err = _parse_function(p_script,p_class,p_class->functions[i]);
		if (err)
			return err;
	}

	//parse static methods

	for(int i=0;i<p_class->static_functions.size();i++) {

		Error err = _parse_function(p_script,p_class,p_class->static_functions[i]);
		if (err)
			return err;
	}


	if (!has_initializer) {
		//create a constructor
		Error err = _parse_function(p_script,p_class,NULL);
		if (err)
			return err;
	}

	return OK;
}
Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {

	uint32_t type = f->get_32();
	print_bl("find property of type: " + itos(type));

	switch (type) {

		case VARIANT_NIL: {

			r_v = Variant();
		} break;
		case VARIANT_BOOL: {

			r_v = bool(f->get_32());
		} break;
		case VARIANT_INT: {

			r_v = int(f->get_32());
		} break;
		case VARIANT_INT64: {

			r_v = int64_t(f->get_64());
		} break;
		case VARIANT_REAL: {

			r_v = f->get_real();
		} break;
		case VARIANT_DOUBLE: {

			r_v = f->get_double();
		} break;
		case VARIANT_STRING: {

			r_v = get_unicode_string();
		} break;
		case VARIANT_VECTOR2: {

			Vector2 v;
			v.x = f->get_real();
			v.y = f->get_real();
			r_v = v;

		} break;
		case VARIANT_RECT2: {

			Rect2 v;
			v.position.x = f->get_real();
			v.position.y = f->get_real();
			v.size.x = f->get_real();
			v.size.y = f->get_real();
			r_v = v;

		} break;
		case VARIANT_VECTOR3: {

			Vector3 v;
			v.x = f->get_real();
			v.y = f->get_real();
			v.z = f->get_real();
			r_v = v;
		} break;
		case VARIANT_PLANE: {

			Plane v;
			v.normal.x = f->get_real();
			v.normal.y = f->get_real();
			v.normal.z = f->get_real();
			v.d = f->get_real();
			r_v = v;
		} break;
		case VARIANT_QUAT: {
			Quat v;
			v.x = f->get_real();
			v.y = f->get_real();
			v.z = f->get_real();
			v.w = f->get_real();
			r_v = v;

		} break;
		case VARIANT_AABB: {

			AABB v;
			v.position.x = f->get_real();
			v.position.y = f->get_real();
			v.position.z = f->get_real();
			v.size.x = f->get_real();
			v.size.y = f->get_real();
			v.size.z = f->get_real();
			r_v = v;

		} break;
		case VARIANT_MATRIX32: {

			Transform2D v;
			v.elements[0].x = f->get_real();
			v.elements[0].y = f->get_real();
			v.elements[1].x = f->get_real();
			v.elements[1].y = f->get_real();
			v.elements[2].x = f->get_real();
			v.elements[2].y = f->get_real();
			r_v = v;

		} break;
		case VARIANT_MATRIX3: {

			Basis v;
			v.elements[0].x = f->get_real();
			v.elements[0].y = f->get_real();
			v.elements[0].z = f->get_real();
			v.elements[1].x = f->get_real();
			v.elements[1].y = f->get_real();
			v.elements[1].z = f->get_real();
			v.elements[2].x = f->get_real();
			v.elements[2].y = f->get_real();
			v.elements[2].z = f->get_real();
			r_v = v;

		} break;
		case VARIANT_TRANSFORM: {

			Transform v;
			v.basis.elements[0].x = f->get_real();
			v.basis.elements[0].y = f->get_real();
			v.basis.elements[0].z = f->get_real();
			v.basis.elements[1].x = f->get_real();
			v.basis.elements[1].y = f->get_real();
			v.basis.elements[1].z = f->get_real();
			v.basis.elements[2].x = f->get_real();
			v.basis.elements[2].y = f->get_real();
			v.basis.elements[2].z = f->get_real();
			v.origin.x = f->get_real();
			v.origin.y = f->get_real();
			v.origin.z = f->get_real();
			r_v = v;
		} break;
		case VARIANT_COLOR: {

			Color v;
			v.r = f->get_real();
			v.g = f->get_real();
			v.b = f->get_real();
			v.a = f->get_real();
			r_v = v;

		} break;

		case VARIANT_NODE_PATH: {

			Vector<StringName> names;
			Vector<StringName> subnames;
			bool absolute;

			int name_count = f->get_16();
			uint32_t subname_count = f->get_16();
			absolute = subname_count & 0x8000;
			subname_count &= 0x7FFF;
			if (ver_format < FORMAT_VERSION_NO_NODEPATH_PROPERTY) {
				subname_count += 1; // has a property field, so we should count it as well
			}

			for (int i = 0; i < name_count; i++)
				names.push_back(_get_string());
			for (uint32_t i = 0; i < subname_count; i++)
				subnames.push_back(_get_string());

			NodePath np = NodePath(names, subnames, absolute);

			r_v = np;

		} break;
		case VARIANT_RID: {

			r_v = f->get_32();
		} break;
		case VARIANT_OBJECT: {

			uint32_t objtype = f->get_32();

			switch (objtype) {

				case OBJECT_EMPTY: {
					//do none

				} break;
				case OBJECT_INTERNAL_RESOURCE: {
					uint32_t index = f->get_32();
					String path = res_path + "::" + itos(index);
					RES res = ResourceLoader::load(path);
					if (res.is_null()) {
						WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
					}
					r_v = res;

				} break;
				case OBJECT_EXTERNAL_RESOURCE: {
					//old file format, still around for compatibility

					String exttype = get_unicode_string();
					String path = get_unicode_string();

					if (path.find("://") == -1 && path.is_rel_path()) {
						// path is relative to file being loaded, so convert to a resource path
						path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
					}

					if (remaps.find(path)) {
						path = remaps[path];
					}

					RES res = ResourceLoader::load(path, exttype);

					if (res.is_null()) {
						WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
					}
					r_v = res;

				} break;
				case OBJECT_EXTERNAL_RESOURCE_INDEX: {
					//new file format, just refers to an index in the external list
					int erindex = f->get_32();

					if (erindex < 0 || erindex >= external_resources.size()) {
						WARN_PRINT("Broken external resource! (index out of size)");
						r_v = Variant();
					} else {

						String exttype = external_resources[erindex].type;
						String path = external_resources[erindex].path;

						if (path.find("://") == -1 && path.is_rel_path()) {
							// path is relative to file being loaded, so convert to a resource path
							path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
						}

						RES res = ResourceLoader::load(path, exttype);

						if (res.is_null()) {
							WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
						}
						r_v = res;
					}

				} break;
				default: {

					ERR_FAIL_V(ERR_FILE_CORRUPT);
				} break;
			}

		} break;
		case VARIANT_DICTIONARY: {

			uint32_t len = f->get_32();
			Dictionary d; //last bit means shared
			len &= 0x7FFFFFFF;
			for (uint32_t i = 0; i < len; i++) {
				Variant key;
				Error err = parse_variant(key);
				ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
				Variant value;
				err = parse_variant(value);
				ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
				d[key] = value;
			}
			r_v = d;
		} break;
		case VARIANT_ARRAY: {

			uint32_t len = f->get_32();
			Array a; //last bit means shared
			len &= 0x7FFFFFFF;
			a.resize(len);
			for (uint32_t i = 0; i < len; i++) {
				Variant val;
				Error err = parse_variant(val);
				ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
				a[i] = val;
			}
			r_v = a;

		} break;
		case VARIANT_RAW_ARRAY: {

			uint32_t len = f->get_32();

			PoolVector<uint8_t> array;
			array.resize(len);
			PoolVector<uint8_t>::Write w = array.write();
			f->get_buffer(w.ptr(), len);
			_advance_padding(len);
			w = PoolVector<uint8_t>::Write();
			r_v = array;

		} break;
		case VARIANT_INT_ARRAY: {

			uint32_t len = f->get_32();

			PoolVector<int> array;
			array.resize(len);
			PoolVector<int>::Write w = array.write();
			f->get_buffer((uint8_t *)w.ptr(), len * 4);
#ifdef BIG_ENDIAN_ENABLED
			{
				uint32_t *ptr = (uint32_t *)w.ptr();
				for (int i = 0; i < len; i++) {

					ptr[i] = BSWAP32(ptr[i]);
				}
			}

#endif
			w = PoolVector<int>::Write();
			r_v = array;
		} break;
		case VARIANT_REAL_ARRAY: {

			uint32_t len = f->get_32();

			PoolVector<real_t> array;
			array.resize(len);
			PoolVector<real_t>::Write w = array.write();
			f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t));
#ifdef BIG_ENDIAN_ENABLED
			{
				uint32_t *ptr = (uint32_t *)w.ptr();
				for (int i = 0; i < len; i++) {

					ptr[i] = BSWAP32(ptr[i]);
				}
			}

#endif

			w = PoolVector<real_t>::Write();
			r_v = array;
		} break;
		case VARIANT_STRING_ARRAY: {

			uint32_t len = f->get_32();
			PoolVector<String> array;
			array.resize(len);
			PoolVector<String>::Write w = array.write();
			for (uint32_t i = 0; i < len; i++)
				w[i] = get_unicode_string();
			w = PoolVector<String>::Write();
			r_v = array;

		} break;
		case VARIANT_VECTOR2_ARRAY: {

			uint32_t len = f->get_32();

			PoolVector<Vector2> array;
			array.resize(len);
			PoolVector<Vector2>::Write w = array.write();
			if (sizeof(Vector2) == 8) {
				f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 2);
#ifdef BIG_ENDIAN_ENABLED
				{
					uint32_t *ptr = (uint32_t *)w.ptr();
					for (int i = 0; i < len * 2; i++) {

						ptr[i] = BSWAP32(ptr[i]);
					}
				}

#endif

			} else {
				ERR_EXPLAIN("Vector2 size is NOT 8!");
				ERR_FAIL_V(ERR_UNAVAILABLE);
			}
			w = PoolVector<Vector2>::Write();
			r_v = array;

		} break;
		case VARIANT_VECTOR3_ARRAY: {

			uint32_t len = f->get_32();

			PoolVector<Vector3> array;
			array.resize(len);
			PoolVector<Vector3>::Write w = array.write();
			if (sizeof(Vector3) == 12) {
				f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 3);
#ifdef BIG_ENDIAN_ENABLED
				{
					uint32_t *ptr = (uint32_t *)w.ptr();
					for (int i = 0; i < len * 3; i++) {

						ptr[i] = BSWAP32(ptr[i]);
					}
				}

#endif

			} else {
				ERR_EXPLAIN("Vector3 size is NOT 12!");
				ERR_FAIL_V(ERR_UNAVAILABLE);
			}
			w = PoolVector<Vector3>::Write();
			r_v = array;

		} break;
		case VARIANT_COLOR_ARRAY: {

			uint32_t len = f->get_32();

			PoolVector<Color> array;
			array.resize(len);
			PoolVector<Color>::Write w = array.write();
			if (sizeof(Color) == 16) {
				f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 4);
#ifdef BIG_ENDIAN_ENABLED
				{
					uint32_t *ptr = (uint32_t *)w.ptr();
					for (int i = 0; i < len * 4; i++) {

						ptr[i] = BSWAP32(ptr[i]);
					}
				}

#endif

			} else {
				ERR_EXPLAIN("Color size is NOT 16!");
				ERR_FAIL_V(ERR_UNAVAILABLE);
			}
			w = PoolVector<Color>::Write();
			r_v = array;
		} break;
#ifndef DISABLE_DEPRECATED
		case VARIANT_IMAGE: {
			uint32_t encoding = f->get_32();
			if (encoding == IMAGE_ENCODING_EMPTY) {
				r_v = Ref<Image>();
				break;
			} else if (encoding == IMAGE_ENCODING_RAW) {
				uint32_t width = f->get_32();
				uint32_t height = f->get_32();
				uint32_t mipmaps = f->get_32();
				uint32_t format = f->get_32();
				const uint32_t format_version_shift = 24;
				const uint32_t format_version_mask = format_version_shift - 1;

				uint32_t format_version = format >> format_version_shift;

				const uint32_t current_version = 0;
				if (format_version > current_version) {

					ERR_PRINT("Format version for encoded binary image is too new");
					return ERR_PARSE_ERROR;
				}

				Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top

				uint32_t datalen = f->get_32();

				PoolVector<uint8_t> imgdata;
				imgdata.resize(datalen);
				PoolVector<uint8_t>::Write w = imgdata.write();
				f->get_buffer(w.ptr(), datalen);
				_advance_padding(datalen);
				w = PoolVector<uint8_t>::Write();

				Ref<Image> image;
				image.instance();
				image->create(width, height, mipmaps, fmt, imgdata);
				r_v = image;

			} else {
				//compressed
				PoolVector<uint8_t> data;
				data.resize(f->get_32());
				PoolVector<uint8_t>::Write w = data.write();
				f->get_buffer(w.ptr(), data.size());
				w = PoolVector<uint8_t>::Write();

				Ref<Image> image;

				if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) {

					image = Image::lossy_unpacker(data);
				} else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) {

					image = Image::lossless_unpacker(data);
				}
				_advance_padding(data.size());

				r_v = image;
			}

		} break;