示例#1
0
文件: main.cpp 项目: BradWBeer/godot
bool Main::start() {

	ERR_FAIL_COND_V(!_start_success,false);

	bool editor=false;
	String doc_tool;
	bool doc_base=true;
	String game_path;
	String script;
	String test;
	String screen;
	String optimize;
	String optimize_preset;
	String _export_platform;
	String _import;
	String _import_script;
	String dumpstrings;
	bool noquit=false;
	bool convert_old=false;
	bool export_debug=false;
	bool project_manager_request = false;
	List<String> args = OS::get_singleton()->get_cmdline_args();
	for (int i=0;i<args.size();i++) {
		//parameters that do not have an argument to the right
		if (args[i]=="-nodocbase") {
			doc_base=false;
		} else if (args[i]=="-noquit") {
			noquit=true;
		} else if (args[i]=="-convert_old") {
			convert_old=true;
		} else if (args[i]=="-editor" || args[i]=="-e") {
			editor=true;
		} else if (args[i] == "-pm" || args[i] == "-project_manager") {
			project_manager_request = true;
		} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
			game_path=args[i];
		}
		//parameters that have an argument to the right
		else if (i < (args.size()-1)) {
			bool parsed_pair=true;
			if (args[i]=="-doctool") {
				doc_tool=args[i+1];
			} else if (args[i]=="-script" || args[i]=="-s") {
				script=args[i+1];
			} else if (args[i]=="-level" || args[i]=="-l") {
				OS::get_singleton()->_custom_level=args[i+1];
			} else if (args[i]=="-test") {
				test=args[i+1];
			} else if (args[i]=="-optimize") {
				optimize=args[i+1];
			} else if (args[i]=="-optimize_preset") {
				optimize_preset=args[i+1];
			} else if (args[i]=="-export") {
				editor=true; //needs editor
				_export_platform=args[i+1];
			} else if (args[i]=="-export_debug") {
				editor=true; //needs editor
				_export_platform=args[i+1];
				export_debug=true;
			} else if (args[i]=="-import") {
				editor=true; //needs editor
				_import=args[i+1];
			} else if (args[i]=="-import_script") {
				editor=true; //needs editor
				_import_script=args[i+1];
			} else if (args[i]=="-dumpstrings") {
				editor=true; //needs editor
				dumpstrings=args[i+1];
			} else {
				// The parameter does not match anything known, don't skip the next argument
				parsed_pair=false;
			}
			if (parsed_pair) {
				i++;
			}
		}
	}

	if (editor)
		Globals::get_singleton()->set("editor_active",true);


	String main_loop_type;
#ifdef TOOLS_ENABLED
	if(doc_tool!="") {

		DocData doc;
		doc.generate(doc_base);

		DocData docsrc;
		if (docsrc.load(doc_tool)==OK) {
			print_line("Doc exists. Merging..");
			doc.merge_from(docsrc);
		} else {
			print_line("No Doc exists. Generating empty.");

		}

		doc.save(doc_tool);

		return false;
	}

	if (optimize!="")
		editor=true; //need editor



#endif

	if (_export_platform!="") {
		if (game_path=="") {
			String err="Command line param ";
			err+=export_debug?"-export_debug":"-export";
			err+=" passed but no destination path given.\n";
			err+="Please specify the binary's file path to export to. Aborting export.";
			ERR_PRINT(err.utf8().get_data());
			return false;
		}
	}

	if(script=="" && game_path=="" && String(GLOBAL_DEF("application/main_scene",""))!="") {
		game_path=GLOBAL_DEF("application/main_scene","");
	}


	MainLoop *main_loop=NULL;
	if (editor) {
		main_loop = memnew(SceneTree);
	};

	if (test!="") {
#ifdef DEBUG_ENABLED
		main_loop = test_main(test,args);

		if (!main_loop)
			return false;

#endif

	} else if (script!="") {

		Ref<Script> script_res = ResourceLoader::load(script);
		ERR_EXPLAIN("Can't load script: "+script);
		ERR_FAIL_COND_V(script_res.is_null(),false);

		if( script_res->can_instance() /*&& script_res->inherits_from("SceneTreeScripted")*/) {


			StringName instance_type=script_res->get_instance_base_type();
			Object *obj = ObjectTypeDB::instance(instance_type);
			MainLoop *script_loop = obj?obj->cast_to<MainLoop>():NULL;
			if (!script_loop) {
				if (obj)
					memdelete(obj);
				ERR_EXPLAIN("Can't load script '"+script+"', it does not inherit from a MainLoop type");
				ERR_FAIL_COND_V(!script_loop,false);
			}


			script_loop->set_init_script(script_res);
			main_loop=script_loop;
		} else {

			return false;
		}

	} else {
		main_loop_type=GLOBAL_DEF("application/main_loop_type","");
	}

	if (!main_loop && main_loop_type=="")
		main_loop_type="SceneTree";

	if (!main_loop) {
		if (!ObjectTypeDB::type_exists(main_loop_type)) {
			OS::get_singleton()->alert("godot: error: MainLoop type doesn't exist: "+main_loop_type);
			return false;
		} else {

			Object *ml = ObjectTypeDB::instance(main_loop_type);
			if (!ml) {
				ERR_EXPLAIN("Can't instance MainLoop type");
				ERR_FAIL_V(false);
			}

			main_loop=ml->cast_to<MainLoop>();
			if (!main_loop) {

				memdelete(ml);
				ERR_EXPLAIN("Invalid MainLoop type");
				ERR_FAIL_V(false);

			}
		}
	}

	if (main_loop->is_type("SceneTree")) {

		SceneTree *sml = main_loop->cast_to<SceneTree>();

		if (debug_collisions) {
			sml->set_debug_collisions_hint(true);
		}
		if (debug_navigation) {
			sml->set_debug_navigation_hint(true);
		}
#ifdef TOOLS_ENABLED


		EditorNode *editor_node=NULL;
		if (editor) {

			editor_node = memnew( EditorNode );
			sml->get_root()->add_child(editor_node);

			//root_node->set_editor(editor);
			//startup editor

			if (_export_platform!="") {

				editor_node->export_platform(_export_platform,game_path,export_debug,"",true);
				game_path=""; //no load anything
			}
		}
#endif

		if (!editor) {
			//standard helpers that can be changed from main config

			String stretch_mode = GLOBAL_DEF("display/stretch_mode","disabled");
			String stretch_aspect = GLOBAL_DEF("display/stretch_aspect","ignore");
			Size2i stretch_size = Size2(GLOBAL_DEF("display/width",0),GLOBAL_DEF("display/height",0));

			SceneTree::StretchMode sml_sm=SceneTree::STRETCH_MODE_DISABLED;
			if (stretch_mode=="2d")
				sml_sm=SceneTree::STRETCH_MODE_2D;
			else if (stretch_mode=="viewport")
				sml_sm=SceneTree::STRETCH_MODE_VIEWPORT;

			SceneTree::StretchAspect sml_aspect=SceneTree::STRETCH_ASPECT_IGNORE;
			if (stretch_aspect=="keep")
				sml_aspect=SceneTree::STRETCH_ASPECT_KEEP;
			else if (stretch_aspect=="keep_width")
				sml_aspect=SceneTree::STRETCH_ASPECT_KEEP_WIDTH;
			else if (stretch_aspect=="keep_height")
				sml_aspect=SceneTree::STRETCH_ASPECT_KEEP_HEIGHT;

			sml->set_screen_stretch(sml_sm,sml_aspect,stretch_size);

			sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true));
			String appname = Globals::get_singleton()->get("application/name");
			appname = TranslationServer::get_singleton()->translate(appname);
			OS::get_singleton()->set_window_title(appname);


		} else {
			GLOBAL_DEF("display/stretch_mode","disabled");
			Globals::get_singleton()->set_custom_property_info("display/stretch_mode",PropertyInfo(Variant::STRING,"display/stretch_mode",PROPERTY_HINT_ENUM,"disabled,2d,viewport"));
			GLOBAL_DEF("display/stretch_aspect","ignore");
			Globals::get_singleton()->set_custom_property_info("display/stretch_aspect",PropertyInfo(Variant::STRING,"display/stretch_aspect",PROPERTY_HINT_ENUM,"ignore,keep,keep_width,keep_height"));
			sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true));


		}


		if (game_path!="" && !project_manager_request) {

			String local_game_path=game_path.replace("\\","/");

			if (!local_game_path.begins_with("res://")) {
				bool absolute=(local_game_path.size()>1) && (local_game_path[0]=='/' || local_game_path[1]==':');

				if (!absolute) {

					if (Globals::get_singleton()->is_using_datapack()) {

						local_game_path="res://"+local_game_path;

					} else {
						int sep=local_game_path.find_last("/");

						if (sep==-1) {
							DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
							local_game_path=da->get_current_dir()+"/"+local_game_path;
							memdelete(da)						;
						} else {

							DirAccess *da = DirAccess::open(local_game_path.substr(0,sep));
							if (da) {
								local_game_path=da->get_current_dir()+"/"+local_game_path.substr(sep+1,local_game_path.length());;
								memdelete(da);
							}
						}
					}

				}
			}

			local_game_path=Globals::get_singleton()->localize_path(local_game_path);

#ifdef TOOLS_ENABLED
			if (editor) {


				if (_import!="") {

					//editor_node->import_scene(_import,local_game_path,_import_script);
					if (!noquit)
						sml->quit();
					game_path=""; //no load anything
				} else {

					Error serr = editor_node->load_scene(local_game_path);

					if (serr==OK) {

						if (optimize!="") {

							editor_node->save_optimized_copy(optimize,optimize_preset);
							if (!noquit)
								sml->quit();
						}

						if (dumpstrings!="") {

							editor_node->save_translatable_strings(dumpstrings);
							if (!noquit)
								sml->quit();
						}
					}
				}
				OS::get_singleton()->set_context(OS::CONTEXT_EDITOR);

				//editor_node->set_edited_scene(game);
			} else {
#endif

				{
					//autoload
					List<PropertyInfo> props;
					Globals::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()) {

						String s = E->get().name;
						if (!s.begins_with("autoload/"))
							continue;
						String name = s.get_slicec('/',1);
						String path = Globals::get_singleton()->get(s);
						bool global_var=false;
						if (path.begins_with("*")) {
							global_var=true;
						}

						if (global_var) {
							for(int i=0;i<ScriptServer::get_language_count();i++) {
								ScriptServer::get_language(i)->add_global_constant(name,Variant());
							}
						}

					}

					//second pass, load into global constants
					List<Node*> to_add;
					for(List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {

						String s = E->get().name;
						if (!s.begins_with("autoload/"))
							continue;
						String name = s.get_slicec('/',1);
						String path = Globals::get_singleton()->get(s);
						bool global_var=false;
						if (path.begins_with("*")) {
							global_var=true;
							path=path.substr(1,path.length()-1);
						}

						RES res = ResourceLoader::load(path);
						ERR_EXPLAIN("Can't autoload: "+path);
						ERR_CONTINUE(res.is_null());
						Node *n=NULL;
						if (res->is_type("PackedScene")) {
							Ref<PackedScene> ps = res;
							n=ps->instance();
						} else if (res->is_type("Script")) {
							Ref<Script> s = res;
							StringName ibt = s->get_instance_base_type();
							bool valid_type = ObjectTypeDB::is_type(ibt,"Node");
							ERR_EXPLAIN("Script does not inherit a Node: "+path);
							ERR_CONTINUE( !valid_type );

							Object *obj = ObjectTypeDB::instance(ibt);

							ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: "+String(ibt));
							ERR_CONTINUE( obj==NULL );

							n = obj->cast_to<Node>();
							n->set_script(s.get_ref_ptr());
						}

						ERR_EXPLAIN("Path in autoload not a node or script: "+path);
						ERR_CONTINUE(!n);
						n->set_name(name);

						//defer so references are all valid on _ready()
						//sml->get_root()->add_child(n);
						to_add.push_back(n);

						if (global_var) {
							for(int i=0;i<ScriptServer::get_language_count();i++) {
								ScriptServer::get_language(i)->add_global_constant(name,n);
							}
						}

					}

					for(List<Node*>::Element *E=to_add.front();E;E=E->next()) {

						sml->get_root()->add_child(E->get());
					}



				}

				Node *scene=NULL;
				Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
				if (scenedata.is_valid())
					scene=scenedata->instance();

				ERR_EXPLAIN("Failed loading scene: "+local_game_path);
				ERR_FAIL_COND_V(!scene,false)
				//sml->get_root()->add_child(scene);
				sml->add_current_scene(scene);

				String iconpath = GLOBAL_DEF("application/icon","Variant()""");
				if (iconpath!="") {
					Image icon;
					if (icon.load(iconpath)==OK)
						OS::get_singleton()->set_icon(icon);
				}


				//singletons
#ifdef TOOLS_ENABLED
			}
#endif
		}

#ifdef TOOLS_ENABLED

		/*if (_export_platform!="") {

			sml->quit();
		}*/

		/*
		if (sml->get_root_node()) {

			Console *console = memnew( Console );

			sml->get_root_node()->cast_to<RootNode>()->set_console(console);
			if (GLOBAL_DEF("console/visible_default",false).operator bool()) {

				console->show();
			} else {P

				console->hide();
			};
		}
*/
		if (project_manager_request || (script=="" && test=="" && game_path=="" && !editor)) {

			ProjectManager *pmanager = memnew( ProjectManager );
			sml->get_root()->add_child(pmanager);
			OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN);
		}

#endif
	}

	OS::get_singleton()->set_main_loop( main_loop );

	return true;
}
示例#2
0
void ResourceFormatSaverTextInstance::_find_resources(const Variant& p_variant,bool p_main) {


	switch(p_variant.get_type()) {
		case Variant::OBJECT: {


			RES res = p_variant.operator RefPtr();

			if (res.is_null() || external_resources.has(res))
				return;

			if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
				int index = external_resources.size();
				external_resources[res]=index;
				return;
			}

			if (resource_set.has(res))
				return;

			List<PropertyInfo> property_list;

			res->get_property_list( &property_list );
			property_list.sort();

			List<PropertyInfo>::Element *I=property_list.front();

			while(I) {

				PropertyInfo pi=I->get();

				if (pi.usage&PROPERTY_USAGE_STORAGE || (bundle_resources && pi.usage&PROPERTY_USAGE_BUNDLE)) {

					Variant v=res->get(I->get().name);
					_find_resources(v);
				}

				I=I->next();
			}

			resource_set.insert( res ); //saved after, so the childs it needs are available when loaded
			saved_resources.push_back(res);

		} break;
		case Variant::ARRAY: {

			Array varray=p_variant;
			int len=varray.size();
			for(int i=0;i<len;i++) {

				Variant v=varray.get(i);
				_find_resources(v);
			}

		} break;
		case Variant::DICTIONARY: {

			Dictionary d=p_variant;
			List<Variant> keys;
			d.get_key_list(&keys);
			for(List<Variant>::Element *E=keys.front();E;E=E->next()) {

				Variant v = d[E->get()];
				_find_resources(v);
			}
		} break;
		default: {}
	}

}
示例#3
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) {
		//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();
				}
				print_verbose("Loading resource: " + local_path + " (cached)");
				return res;
			}
		}
		if (ResourceCache::lock) {
			ResourceCache::lock->read_unlock();
		}
	}

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

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

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

	if (res.is_null()) {
		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

	return res;
}
示例#4
0
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {

	Object *obj = ObjectDB::get_instance(p_id);
	if (!obj)
		return;

	typedef Pair<PropertyInfo, Variant> PropertyDesc;
	List<PropertyDesc> properties;

	if (ScriptInstance *si = obj->get_script_instance()) {
		if (!si->get_script().is_null()) {

			Set<StringName> members;
			si->get_script()->get_members(&members);
			for (Set<StringName>::Element *E = members.front(); E; E = E->next()) {

				Variant m;
				if (si->get(E->get(), m)) {
					PropertyInfo pi(m.get_type(), String("Members/") + E->get());
					properties.push_back(PropertyDesc(pi, m));
				}
			}

			Map<StringName, Variant> constants;
			si->get_script()->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				PropertyInfo pi(E->value().get_type(), (String("Constants/") + E->key()));
				properties.push_back(PropertyDesc(pi, E->value()));
			}
		}
	}
	if (Node *node = Object::cast_to<Node>(obj)) {
		PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
		properties.push_front(PropertyDesc(pi, node->get_path()));
	} else if (Resource *res = Object::cast_to<Resource>(obj)) {
		if (Script *s = Object::cast_to<Script>(res)) {
			Map<StringName, Variant> constants;
			s->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key());
				properties.push_front(PropertyDesc(pi, E->value()));
			}
		}
	}

	List<PropertyInfo> pinfo;
	obj->get_property_list(&pinfo, true);
	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) {
			properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name)));
		}
	}

	Array send_props;
	for (int i = 0; i < properties.size(); i++) {
		const PropertyInfo &pi = properties[i].first;
		Variant &var = properties[i].second;

		WeakRef *ref = Object::cast_to<WeakRef>(var);
		if (ref) {
			var = ref->get_ref();
		}

		RES res = var;

		Array prop;
		prop.push_back(pi.name);
		prop.push_back(pi.type);

		//only send information that can be sent..
		int len = 0; //test how big is this to encode
		encode_variant(var, NULL, len);
		if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
			prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG);
			prop.push_back("");
			prop.push_back(pi.usage);
			prop.push_back(Variant());
		} else {
			prop.push_back(pi.hint);
			if (res.is_null())
				prop.push_back(pi.hint_string);
			else
				prop.push_back(String("RES:") + res->get_path());
			prop.push_back(pi.usage);
			prop.push_back(var);
		}
		send_props.push_back(prop);
	}

	packet_peer_stream->put_var("message:inspect_object");
	packet_peer_stream->put_var(3);
	packet_peer_stream->put_var(p_id);
	packet_peer_stream->put_var(obj->get_class());
	packet_peer_stream->put_var(send_props);
}
示例#5
0
Error _ResourceSaver::save(const String &p_path,const RES& p_resource, uint32_t p_flags) {

    ERR_FAIL_COND_V(p_resource.is_null(),ERR_INVALID_PARAMETER);
    return ResourceSaver::save(p_path,p_resource, p_flags);
}
示例#6
0
void PhysicsShapeQueryParameters::set_shape(const RES &p_shape) {

	ERR_FAIL_COND(p_shape.is_null());
	shape=p_shape->get_rid();
}
Error ResourceInteractiveLoaderBinary::poll(){

	if (error!=OK)
		return error;


	int s = stage;

	if (s<external_resources.size()) {

		RES res = ResourceLoader::load(external_resources[s].path,external_resources[s].type);
		if (res.is_null()) {

			if (!ResourceLoader::get_abort_on_missing_resources()) {

				ResourceLoader::notify_load_error("Resource Not Found: "+external_resources[s].path);
			} else {


				error=ERR_FILE_CORRUPT;
				ERR_EXPLAIN("Can't load dependency: "+external_resources[s].path);
				ERR_FAIL_V(error);
			}

		} else {
			resource_cache.push_back(res);
		}

		stage++;
		return OK;
	}

	s-=external_resources.size();


	if (s>=internal_resources.size()) {

		error=ERR_BUG;
		ERR_FAIL_COND_V(s>=internal_resources.size(),error);
	}

	bool main = s==(internal_resources.size()-1);

	//maybe it is loaded already
	String path;



	if (!main) {

		path=internal_resources[s].path;
		if (path.begins_with("local://"))
			path=path.replace("local://",res_path+"::");



		if (ResourceCache::has(path)) {
			//already loaded, don't do anything
			stage++;
			error=OK;
			return error;
		}
	} else {

		path=res_path;
	}

	uint64_t offset = internal_resources[s].offset;

	f->seek(offset);

	String t = get_unicode_string();

	Object *obj = ObjectTypeDB::instance(t);
	if (!obj) {
		error=ERR_FILE_CORRUPT;
		ERR_EXPLAIN(local_path+":Resource of unrecognized type in file: "+t);
	}
	ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT);

	Resource *r = obj->cast_to<Resource>();
	if (!r) {
		error=ERR_FILE_CORRUPT;
		memdelete(obj); //bye
		ERR_EXPLAIN(local_path+":Resoucre type in resource field not a resource, type is: "+obj->get_type());
		ERR_FAIL_COND_V(!r,ERR_FILE_CORRUPT);
	}

	RES res = RES( r );

	r->set_path(path);

	int pc = f->get_32();

	//set properties

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

		uint32_t name_idx = f->get_32();
		if (name_idx>=(uint32_t)string_map.size()) {
			error=ERR_FILE_CORRUPT;
			ERR_FAIL_V(ERR_FILE_CORRUPT);
		}

		Variant value;

		error = parse_variant(value);
		if (error)
			return error;

		res->set(string_map[name_idx],value);
	}
#ifdef TOOLS_ENABLED
	res->set_edited(false);
#endif
	stage++;

	resource_cache.push_back(res);

	if (main) {
		if (importmd_ofs) {

			f->seek(importmd_ofs);
			Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
			imd->set_editor(get_unicode_string());
			int sc = f->get_32();
			for(int i=0;i<sc;i++) {

				String src = get_unicode_string();
				String md5 = get_unicode_string();
				imd->add_source(src,md5);
			}
			int pc = f->get_32();

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

				String name = get_unicode_string();
				Variant val;
				parse_variant(val);
				imd->set_option(name,val);
			}
			res->set_import_metadata(imd);

		}
		f->close();
		resource=res;
		error=ERR_FILE_EOF;

	} else {
		error=OK;
	}

	return OK;

}
示例#8
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);

	local_path=find_complete_path(local_path,p_type_hint);
	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 ) );
	}

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

	if (OS::get_singleton()->is_stdout_verbose())
		print_line("load resource: "+remapped_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;
		RES res = loader[i]->load(remapped_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(remapped_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();
}
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

}
示例#10
0
void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant,bool p_main) {


	switch(p_variant.get_type()) {
		case Variant::OBJECT: {


			RES res = p_variant.operator RefPtr();

			if (res.is_null())
				return;

			if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
				external_resources.insert(res);
				return;
			}


			if (resource_map.has(res))
				return;

			List<PropertyInfo> property_list;

			res->get_property_list(&property_list);

			for(List<PropertyInfo>::Element *E=property_list.front();E;E=E->next()) {

				if (E->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && E->get().usage&PROPERTY_USAGE_BUNDLE)) {

					_find_resources(res->get(E->get().name));
				}
			}

			resource_map[ res ] = saved_resources.size();
			saved_resources.push_back(res);

		} break;

		case Variant::ARRAY: {

			Array varray=p_variant;
			int len=varray.size();
			for(int i=0;i<len;i++) {

				Variant v=varray.get(i);
				_find_resources(v);
			}

		} break;

		case Variant::DICTIONARY: {

			Dictionary d=p_variant;
			List<Variant> keys;
			d.get_key_list(&keys);
			for(List<Variant>::Element *E=keys.front();E;E=E->next()) {

				_find_resources(E->get());
				Variant v = d[E->get()];
				_find_resources(v);
			}
		} break;
		case Variant::NODE_PATH: {
			//take the chance and save node path strings
			NodePath np = p_variant;
			for(int i=0;i<np.get_name_count();i++)
				get_string_index(np.get_name(i));
			for(int i=0;i<np.get_subname_count();i++)
				get_string_index(np.get_subname(i));
			get_string_index(np.get_property());


		} break;

		default: {}
	}

}
示例#11
0
void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,const PropertyInfo& p_hint) {

	switch(p_property.get_type()) {

		case Variant::NIL: {

			f->store_32(VARIANT_NIL);
			// don't store anything
		} break;
		case Variant::BOOL: {

			f->store_32(VARIANT_BOOL);
			bool val=p_property;
			f->store_32(val);
		} break;
		case Variant::INT: {

			f->store_32(VARIANT_INT);
			int val=p_property;
			f->store_32(val);
		} break;
		case Variant::REAL: {

			f->store_32(VARIANT_REAL);
			real_t val=p_property;
			f->store_real(val);

		} break;
		case Variant::STRING: {

			f->store_32(VARIANT_STRING);
			String val=p_property;
			save_unicode_string(val);

		} break;
		case Variant::VECTOR2: {

			f->store_32(VARIANT_VECTOR2);
			Vector2 val=p_property;
			f->store_real(val.x);
			f->store_real(val.y);

		} break;
		case Variant::RECT2: {

			f->store_32(VARIANT_RECT2);
			Rect2 val=p_property;
			f->store_real(val.pos.x);
			f->store_real(val.pos.y);
			f->store_real(val.size.x);
			f->store_real(val.size.y);

		} break;
		case Variant::VECTOR3: {

			f->store_32(VARIANT_VECTOR3);
			Vector3 val=p_property;
			f->store_real(val.x);
			f->store_real(val.y);
			f->store_real(val.z);

		} break;
		case Variant::PLANE: {

			f->store_32(VARIANT_PLANE);
			Plane val=p_property;
			f->store_real(val.normal.x);
			f->store_real(val.normal.y);
			f->store_real(val.normal.z);
			f->store_real(val.d);

		} break;
		case Variant::QUAT: {

			f->store_32(VARIANT_QUAT);
			Quat val=p_property;
			f->store_real(val.x);
			f->store_real(val.y);
			f->store_real(val.z);
			f->store_real(val.w);

		} break;
		case Variant::_AABB: {

			f->store_32(VARIANT_AABB);
			AABB val=p_property;
			f->store_real(val.pos.x);
			f->store_real(val.pos.y);
			f->store_real(val.pos.z);
			f->store_real(val.size.x);
			f->store_real(val.size.y);
			f->store_real(val.size.z);

		} break;
		case Variant::MATRIX32: {

			f->store_32(VARIANT_MATRIX32);
			Matrix32 val=p_property;
			f->store_real(val.elements[0].x);
			f->store_real(val.elements[0].y);
			f->store_real(val.elements[1].x);
			f->store_real(val.elements[1].y);
			f->store_real(val.elements[2].x);
			f->store_real(val.elements[2].y);

		} break;
		case Variant::MATRIX3: {

			f->store_32(VARIANT_MATRIX3);
			Matrix3 val=p_property;
			f->store_real(val.elements[0].x);
			f->store_real(val.elements[0].y);
			f->store_real(val.elements[0].z);
			f->store_real(val.elements[1].x);
			f->store_real(val.elements[1].y);
			f->store_real(val.elements[1].z);
			f->store_real(val.elements[2].x);
			f->store_real(val.elements[2].y);
			f->store_real(val.elements[2].z);

		} break;
		case Variant::TRANSFORM: {

			f->store_32(VARIANT_TRANSFORM);
			Transform val=p_property;
			f->store_real(val.basis.elements[0].x);
			f->store_real(val.basis.elements[0].y);
			f->store_real(val.basis.elements[0].z);
			f->store_real(val.basis.elements[1].x);
			f->store_real(val.basis.elements[1].y);
			f->store_real(val.basis.elements[1].z);
			f->store_real(val.basis.elements[2].x);
			f->store_real(val.basis.elements[2].y);
			f->store_real(val.basis.elements[2].z);
			f->store_real(val.origin.x);
			f->store_real(val.origin.y);
			f->store_real(val.origin.z);

		} break;
		case Variant::COLOR: {

			f->store_32(VARIANT_COLOR);
			Color val=p_property;
			f->store_real(val.r);
			f->store_real(val.g);
			f->store_real(val.b);
			f->store_real(val.a);

		} break;
		case Variant::IMAGE: {

			f->store_32(VARIANT_IMAGE);
			Image val =p_property;
			if (val.empty()) {
				f->store_32(IMAGE_ENCODING_EMPTY);
				break;
			}

			int encoding=IMAGE_ENCODING_RAW;
			float quality=0.7;

			if (val.get_format() <= Image::FORMAT_INDEXED_ALPHA) {
				//can only compress uncompressed stuff

				if (p_hint.hint==PROPERTY_HINT_IMAGE_COMPRESS_LOSSY && Image::lossy_packer) {
					encoding=IMAGE_ENCODING_LOSSY;
					float qs=p_hint.hint_string.to_double();
					if (qs!=0.0)
						quality=qs;

				} else if (p_hint.hint==PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS && Image::lossless_packer) {
					encoding=IMAGE_ENCODING_LOSSLESS;

				}
			}

			f->store_32(encoding); //raw encoding

			if (encoding==IMAGE_ENCODING_RAW) {


				f->store_32(val.get_width());
				f->store_32(val.get_height());
				f->store_32(val.get_mipmaps());
				switch(val.get_format()) {

					case Image::FORMAT_GRAYSCALE: f->store_32(IMAGE_FORMAT_GRAYSCALE ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255
					case Image::FORMAT_INTENSITY: f->store_32(IMAGE_FORMAT_INTENSITY ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255
					case Image::FORMAT_GRAYSCALE_ALPHA: f->store_32(IMAGE_FORMAT_GRAYSCALE_ALPHA ); break; ///< two bytes per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255. alpha 0-255
					case Image::FORMAT_RGB: f->store_32(IMAGE_FORMAT_RGB ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B
					case Image::FORMAT_RGBA: f->store_32(IMAGE_FORMAT_RGBA ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B: f->store_32(IMAGE_FORMAT_ ); break; one byte A
					case Image::FORMAT_INDEXED: f->store_32(IMAGE_FORMAT_INDEXED ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*3 bytes of palette
					case Image::FORMAT_INDEXED_ALPHA: f->store_32(IMAGE_FORMAT_INDEXED_ALPHA ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*4 bytes of palette (alpha)
					case Image::FORMAT_BC1: f->store_32(IMAGE_FORMAT_BC1 ); break; // DXT1
					case Image::FORMAT_BC2: f->store_32(IMAGE_FORMAT_BC2 ); break; // DXT3
					case Image::FORMAT_BC3: f->store_32(IMAGE_FORMAT_BC3 ); break; // DXT5
					case Image::FORMAT_BC4: f->store_32(IMAGE_FORMAT_BC4 ); break; // ATI1
					case Image::FORMAT_BC5: f->store_32(IMAGE_FORMAT_BC5 ); break; // ATI2
					case Image::FORMAT_PVRTC2: f->store_32(IMAGE_FORMAT_PVRTC2 ); break;
					case Image::FORMAT_PVRTC2_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC2_ALPHA ); break;
					case Image::FORMAT_PVRTC4: f->store_32(IMAGE_FORMAT_PVRTC4 ); break;
					case Image::FORMAT_PVRTC4_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC4_ALPHA ); break;
					case Image::FORMAT_ETC: f->store_32(IMAGE_FORMAT_ETC); break;
					case Image::FORMAT_CUSTOM: f->store_32(IMAGE_FORMAT_CUSTOM ); break;
					default: {}

				}

				int dlen = val.get_data().size();
				f->store_32(dlen);
				DVector<uint8_t>::Read r = val.get_data().read();
				f->store_buffer(r.ptr(),dlen);
				_pad_buffer(dlen);
			} else {

				DVector<uint8_t> data;
				if (encoding==IMAGE_ENCODING_LOSSY) {
					data=Image::lossy_packer(val,quality);

				} else if (encoding==IMAGE_ENCODING_LOSSLESS) {
					data=Image::lossless_packer(val);

				}

				int ds=data.size();
				f->store_32(ds);
				if (ds>0) {
					DVector<uint8_t>::Read r = data.read();
					f->store_buffer(r.ptr(),ds);

					_pad_buffer(ds);

				}
			}

		} break;
		case Variant::NODE_PATH: {
			f->store_32(VARIANT_NODE_PATH);
			NodePath np=p_property;
			f->store_16(np.get_name_count());
			uint16_t snc = np.get_subname_count();
			if (np.is_absolute())
				snc|=0x8000;
			f->store_16(snc);
			for(int i=0;i<np.get_name_count();i++)
				f->store_32(get_string_index(np.get_name(i)));
			for(int i=0;i<np.get_subname_count();i++)
				f->store_32(get_string_index(np.get_subname(i)));
			f->store_32(get_string_index(np.get_property()));

		} break;
		case Variant::_RID: {

			f->store_32(VARIANT_RID);
			WARN_PRINT("Can't save RIDs");
			RID val = p_property;
			f->store_32(val.get_id());
		} break;
		case Variant::OBJECT: {

			f->store_32(VARIANT_OBJECT);
			RES res = p_property;
			if (res.is_null()) {
				f->store_32(OBJECT_EMPTY);
				return; // don't save it
			}

			if (res->get_path().length() && res->get_path().find("::")==-1) {
				f->store_32(OBJECT_EXTERNAL_RESOURCE);
				save_unicode_string(res->get_save_type());
				String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
				if (no_extensions)
					path=path.basename()+".*";
				save_unicode_string(path);
			} else {

				if (!resource_map.has(res)) {
					f->store_32(OBJECT_EMPTY);
					ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
					ERR_FAIL();
				}

				f->store_32(OBJECT_INTERNAL_RESOURCE);
				f->store_32(resource_map[res]);
				//internal resource
			}


		} break;
		case Variant::INPUT_EVENT: {

			f->store_32(VARIANT_INPUT_EVENT);
			WARN_PRINT("Can't save InputEvent (maybe it could..)");
		} break;
		case Variant::DICTIONARY: {

			f->store_32(VARIANT_DICTIONARY);
			Dictionary d = p_property;
            f->store_32(uint32_t(d.size())|(d.is_shared()?0x80000000:0));

			List<Variant> keys;
			d.get_key_list(&keys);

			for(List<Variant>::Element *E=keys.front();E;E=E->next()) {

				//if (!_check_type(dict[E->get()]))
				//	continue;

				write_variant(E->get());
				write_variant(d[E->get()]);
			}


		} break;
		case Variant::ARRAY: {

			f->store_32(VARIANT_ARRAY);
			Array a=p_property;
			f->store_32(uint32_t(a.size())|(a.is_shared()?0x80000000:0));
			for(int i=0;i<a.size();i++) {

				write_variant(a[i]);
			}

		} break;
		case Variant::RAW_ARRAY: {

			f->store_32(VARIANT_RAW_ARRAY);
			DVector<uint8_t> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<uint8_t>::Read r = arr.read();
			f->store_buffer(r.ptr(),len);
			_pad_buffer(len);

		} break;
		case Variant::INT_ARRAY: {

			f->store_32(VARIANT_INT_ARRAY);
			DVector<int> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<int>::Read r = arr.read();
			for(int i=0;i<len;i++)
				f->store_32(r[i]);

		} break;
		case Variant::REAL_ARRAY: {

			f->store_32(VARIANT_REAL_ARRAY);
			DVector<real_t> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<real_t>::Read r = arr.read();
			for(int i=0;i<len;i++) {
				f->store_real(r[i]);
			}

		} break;
		case Variant::STRING_ARRAY: {

			f->store_32(VARIANT_STRING_ARRAY);
			DVector<String> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<String>::Read r = arr.read();
			for(int i=0;i<len;i++) {
				save_unicode_string(r[i]);
			}

		} break;
		case Variant::VECTOR3_ARRAY: {

			f->store_32(VARIANT_VECTOR3_ARRAY);
			DVector<Vector3> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<Vector3>::Read r = arr.read();
			for(int i=0;i<len;i++) {
				f->store_real(r[i].x);
				f->store_real(r[i].y);
				f->store_real(r[i].z);
			}

		} break;
		case Variant::VECTOR2_ARRAY: {

			f->store_32(VARIANT_VECTOR2_ARRAY);
			DVector<Vector2> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<Vector2>::Read r = arr.read();
			for(int i=0;i<len;i++) {
				f->store_real(r[i].x);
				f->store_real(r[i].y);
			}

		} break;
		case Variant::COLOR_ARRAY: {

			f->store_32(VARIANT_COLOR_ARRAY);
			DVector<Color> arr = p_property;
			int len=arr.size();
			f->store_32(len);
			DVector<Color>::Read r = arr.read();
			for(int i=0;i<len;i++) {
				f->store_real(r[i].r);
				f->store_real(r[i].g);
				f->store_real(r[i].b);
				f->store_real(r[i].a);
			}

		} break;
		default: {

			ERR_EXPLAIN("Invalid variant");
			ERR_FAIL();
		}
	}
}
示例#12
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);

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

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

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

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

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

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

	// 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;
		}
		found = true;
		RES res = loader[i]->load(path, path, r_error);
		if (res.is_null()) {
			continue;
		}
		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

		return res;
	}

	if (found) {
		ERR_EXPLAIN("Failed loading resource: " + path);
	} else {
		ERR_EXPLAIN("No loader found for resource: " + path);
	}
	ERR_FAIL_V(RES());
	return RES();
}
示例#13
0
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 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: {
					//old file format, still around for compatibility

					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 = 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, type);

					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 type = 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, 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_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;
示例#14
0
Error ResourceInteractiveLoaderText::poll() {

	if (error!=OK)
		return error;

	if (next_tag.name=="ext_resource") {


		if (!next_tag.fields.has("path")) {
			error=ERR_FILE_CORRUPT;
			error_text="Missing 'path' in external resource tag";
			_printerr();
			return error;
		}

		if (!next_tag.fields.has("type")) {
			error=ERR_FILE_CORRUPT;
			error_text="Missing 'type' in external resource tag";
			_printerr();
			return error;
		}

		if (!next_tag.fields.has("id")) {
			error=ERR_FILE_CORRUPT;
			error_text="Missing 'id' in external resource tag";
			_printerr();
			return error;
		}

		String path=next_tag.fields["path"];
		String type=next_tag.fields["type"];
		int index=next_tag.fields["id"];


		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(local_path.get_base_dir().plus_file(path));
		}

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

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

		if (res.is_null()) {

			if (ResourceLoader::get_abort_on_missing_resources()) {
				error=ERR_FILE_CORRUPT;
				error_text="[ext_resource] referenced nonexistent resource at: "+path;
				_printerr();
				return error;
			} else {
				ResourceLoader::notify_dependency_error(local_path,path,type);
			}
		} else {

			resource_cache.push_back(res);
		}

		ExtResource er;
		er.path=path;
		er.type=type;
		ext_resources[index]=er;

		error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);

		if (error) {
			_printerr();
		}

		resource_current++;
		return error;


	} else if (next_tag.name=="sub_resource") {


		if (!next_tag.fields.has("type")) {
			error=ERR_FILE_CORRUPT;
			error_text="Missing 'type' in external resource tag";
			_printerr();
			return error;
		}

		if (!next_tag.fields.has("id")) {
			error=ERR_FILE_CORRUPT;
			error_text="Missing 'index' in external resource tag";
			_printerr();
			return error;
		}

		String type=next_tag.fields["type"];
		int id=next_tag.fields["id"];

		String path = local_path+"::"+itos(id);


		//bool exists=ResourceCache::has(path);

		Ref<Resource> res;

		if ( !ResourceCache::has(path)) { //only if it doesn't exist

			Object *obj = ObjectTypeDB::instance(type);
			if (!obj) {

				error_text+="Can't create sub resource of type: "+type;
				_printerr();
				error=ERR_FILE_CORRUPT;
				return error;
			}


			Resource *r = obj->cast_to<Resource>();
			if (!r) {

				error_text+="Can't create sub resource of type, because not a resource: "+type;
				_printerr();
				error=ERR_FILE_CORRUPT;
				return error;
			}

			res=Ref<Resource>(r);
			resource_cache.push_back(res);
			res->set_path(path);

		}

		resource_current++;

		while(true) {

			String assign;
			Variant value;

			error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);

			if (error) {
				_printerr();
				return error;
			}

			if (assign!=String()) {
				if (res.is_valid()) {
					res->set(assign,value);
				}
				//it's assignment
			} else if (next_tag.name!=String()) {

				error=OK;
				break;
			} else {
				error=ERR_FILE_CORRUPT;
				error_text="Premature end of file while parsing [sub_resource]";
				_printerr();
				return error;
			}


		}

		return OK;

	} else if (next_tag.name=="resource") {

		if (is_scene) {

			error_text+="found the 'resource' tag on a scene file!";
			_printerr();
			error=ERR_FILE_CORRUPT;
			return error;
		}

		Object *obj = ObjectTypeDB::instance(res_type);
		if (!obj) {

			error_text+="Can't create sub resource of type: "+res_type;
			_printerr();
			error=ERR_FILE_CORRUPT;
			return error;
		}


		Resource *r = obj->cast_to<Resource>();
		if (!r) {

			error_text+="Can't create sub resource of type, because not a resource: "+res_type;
			_printerr();
			error=ERR_FILE_CORRUPT;
			return error;
		}

		resource=Ref<Resource>(r);

		resource_current++;

		while(true) {

			String assign;
			Variant value;

			error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);

			if (error) {
				if (error!=ERR_FILE_EOF) {
					_printerr();
				} else {
					if (!ResourceCache::has(res_path)) {
						resource->set_path(res_path);
					}
				}
				return error;
			}

			if (assign!=String()) {
				resource->set(assign,value);
				//it's assignment
			} else if (next_tag.name!=String()) {

				error=ERR_FILE_CORRUPT;
				error_text="Extra tag found when parsing main resource file";
				_printerr();
				return error;
			} else {
				error=ERR_FILE_EOF;
				return error;
			}

		}

		return OK;

	} else if (next_tag.name=="node") {

		if (!is_scene) {

			error_text+="found the 'node' tag on a resource file!";
			_printerr();
			error=ERR_FILE_CORRUPT;
			return error;
		}

		/*
		int add_name(const StringName& p_name);
		int add_value(const Variant& p_value);
		int add_node_path(const NodePath& p_path);
		int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance);
		void add_node_property(int p_node,int p_name,int p_value);
		void add_node_group(int p_node,int p_group);
		void set_base_scene(int p_idx);
		void add_connection(int p_from,int p_to, int p_signal, int p_method, int p_flags,const Vector<int>& p_binds);
		void add_editable_instance(const NodePath& p_path);

		*/

		int parent=-1;
		int owner=-1;
		int type=-1;
		int name=-1;
		int instance=-1;
//		int base_scene=-1;

		if (next_tag.fields.has("name")) {
			name=packed_scene->get_state()->add_name(next_tag.fields["name"]);
		}

		if (next_tag.fields.has("parent")) {
			NodePath np = next_tag.fields["parent"];
			np.prepend_period(); //compatible to how it manages paths internally
			parent=packed_scene->get_state()->add_node_path(np);
		}



		if (next_tag.fields.has("type")) {
			type=packed_scene->get_state()->add_name(next_tag.fields["type"]);
		} else {
			type=SceneState::TYPE_INSTANCED; //no type? assume this was instanced
		}


		if (next_tag.fields.has("instance")) {

			instance=packed_scene->get_state()->add_value(next_tag.fields["instance"]);

			if (packed_scene->get_state()->get_node_count()==0 && parent==-1) {
				packed_scene->get_state()->set_base_scene(instance);
				instance=-1;
			}
		}

		if (next_tag.fields.has("instance_placeholder")) {

			String path=next_tag.fields["instance_placeholder"];

			int path_v = packed_scene->get_state()->add_value(path);

			if (packed_scene->get_state()->get_node_count()==0) {
				error=ERR_FILE_CORRUPT;
				error_text="Instance Placeholder can't be used for inheritance.";
				_printerr();
				return error;
			}

			instance=path_v|SceneState::FLAG_INSTANCE_IS_PLACEHOLDER;
		}

		if (next_tag.fields.has("owner")) {
			owner=packed_scene->get_state()->add_node_path(next_tag.fields["owner"]);
		} else {
			if (parent!=-1 && !(type==SceneState::TYPE_INSTANCED && instance==-1))
				owner=0; //if no owner, owner is root
		}

		int node_id = packed_scene->get_state()->add_node(parent,owner,type,name,instance);

		if (next_tag.fields.has("groups")) {

			Array groups = next_tag.fields["groups"];
			for (int i=0;i<groups.size();i++) {
				packed_scene->get_state()->add_node_group(node_id,packed_scene->get_state()->add_name(groups[i]));
			}
		}

		while(true) {

			String assign;
			Variant value;

			error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);

			if (error) {
				if (error!=ERR_FILE_EOF) {
					_printerr();
				} else {
					resource=packed_scene;
					if (!ResourceCache::has(res_path)) {
						packed_scene->set_path(res_path);
					}
				}
				return error;
			}

			if (assign!=String()) {
				int nameidx = packed_scene->get_state()->add_name(assign);
				int valueidx = packed_scene->get_state()->add_value(value);
				packed_scene->get_state()->add_node_property(node_id,nameidx,valueidx);
				//it's assignment
			} else if (next_tag.name!=String()) {

				error=OK;
				return error;
			} else {

				resource=packed_scene;
				error=ERR_FILE_EOF;
				return error;
			}

		}

		return OK;

	} else if (next_tag.name=="connection") {

		if (!is_scene) {

			error_text+="found the 'connection' tag on a resource file!";
			_printerr();
			error=ERR_FILE_CORRUPT;
			return error;
		}

		if (!next_tag.fields.has("from")) {
			error=ERR_FILE_CORRUPT;
			error_text="missing 'from' field fron connection tag";
			return error;
		}

		if (!next_tag.fields.has("to")) {
			error=ERR_FILE_CORRUPT;
			error_text="missing 'to' field fron connection tag";
			return error;
		}

		if (!next_tag.fields.has("signal")) {
			error=ERR_FILE_CORRUPT;
			error_text="missing 'signal' field fron connection tag";
			return error;
		}

		if (!next_tag.fields.has("method")) {
			error=ERR_FILE_CORRUPT;
			error_text="missing 'method' field fron connection tag";
			return error;
		}

		NodePath from = next_tag.fields["from"];
		NodePath to = next_tag.fields["to"];
		StringName method = next_tag.fields["method"];
		StringName signal = next_tag.fields["signal"];
		int flags=CONNECT_PERSIST;
		Array binds;

		if (next_tag.fields.has("flags")) {
			flags=next_tag.fields["flags"];
		}

		if (next_tag.fields.has("binds")) {
			binds=next_tag.fields["binds"];
		}

		Vector<int> bind_ints;
		for(int i=0;i<binds.size();i++) {
			bind_ints.push_back( packed_scene->get_state()->add_value( binds[i] ) );
		}

		packed_scene->get_state()->add_connection(
					packed_scene->get_state()->add_node_path(from.simplified()),
					packed_scene->get_state()->add_node_path(to.simplified()),
					packed_scene->get_state()->add_name(signal),
					packed_scene->get_state()->add_name(method),
					flags,
					bind_ints
					);

		error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);

		if (error) {
			if (error!=ERR_FILE_EOF) {
				_printerr();
			} else {
				resource=packed_scene;
			}
		}

		return error;
	} else if (next_tag.name=="editable") {

		if (!is_scene) {

			error_text+="found the 'editable' tag on a resource file!";
			_printerr();
			error=ERR_FILE_CORRUPT;
			return error;
		}

		if (!next_tag.fields.has("path")) {
			error=ERR_FILE_CORRUPT;
			error_text="missing 'path' field fron connection tag";
			_printerr();
			return error;
		}

		NodePath path = next_tag.fields["path"];

		packed_scene->get_state()->add_editable_instance(path.simplified());

		error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);

		if (error) {
			if (error!=ERR_FILE_EOF) {
				_printerr();
			} else {
				resource=packed_scene;
			}
		}

		return error;

	} else {

		error_text+="Unknown tag in file: "+next_tag.name;
		_printerr();
		error=ERR_FILE_CORRUPT;
		return error;
	}

	return OK;
}
示例#15
0
MainLoop* test() {

	print_line("this is test io");
	DirAccess* da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
	da->change_dir(".");
	print_line("Opening current dir "+ da->get_current_dir());
	String entry;
	da->list_dir_begin();
	while ( (entry = da->get_next()) != "") {

		print_line("entry "+entry+" is dir: " + Variant(da->current_is_dir()));
	};
	da->list_dir_end();

	RES texture = ResourceLoader::load("test_data/rock.png");
	ERR_FAIL_COND_V(texture.is_null(), NULL);

	ResourceSaver::save("test_data/rock.xml",texture);

	print_line("localize paths");
	print_line(Globals::get_singleton()->localize_path("algo.xml"));
	print_line(Globals::get_singleton()->localize_path("c:\\windows\\algo.xml"));
	print_line(Globals::get_singleton()->localize_path(Globals::get_singleton()->get_resource_path()+"/something/something.xml"));
	print_line(Globals::get_singleton()->localize_path("somedir/algo.xml"));

	{

		FileAccess* z = FileAccess::open("test_data/archive.zip", FileAccess::READ);
		int len = z->get_len();
		Vector<uint8_t> zip;
		zip.resize(len);
		z->get_buffer(&zip[0], len);
		z->close();
		memdelete(z);

		FileAccessMemory::register_file("a_package", zip);
		FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_RESOURCES);
		FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_FILESYSTEM);
		FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_USERDATA);

		print_line("archive test");
#if 0
		Archive arch;

		Archive::get_singleton()->add_package("a_package");
		FileAccessArchive f;

		print_line("opening for read");
		f._open("file.txt", FileAccess::READ);
		int pos = f.get_pos();
		printf("file has %i bytes, initial pos %i\n", (int)f.get_len(), pos);

		do {
			printf("%c", f.get_8());

		} while (!f.eof_reached());

		print_line("opening for stored seek");
		f.open("seek.bin", FileAccess::READ);
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		f.seek(128);
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());

		print_line("opening for deflated seek");
		f.open("seek_deflated.bin", FileAccess::READ);
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		f.seek(128);
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		f.seek(256);
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		f.seek(4);
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());
		pos = f.get_pos();
		printf("byte at pos %i is %i\n", pos, (int)f.get_8());

		f.close();

		DirAccessArchive d;
		String dir = "../blah1/blah2/blahask/../blah3/.//blah4/";
		printf("changing dir to %s\n", dir.utf8().get_data());
		d.change_dir(dir);
		printf("current dir is %s\n", d.get_current_dir().utf8().get_data());

		FileAccessMemory::cleanup();
#endif
	};

	print_line("test done");


	return memnew( TestMainLoop );

}
示例#16
0
void AnimationCache::_update_cache() {

	cache_valid=false;

	ERR_FAIL_COND(!root);
	ERR_FAIL_COND(!root->is_inside_tree());
	ERR_FAIL_COND(animation.is_null());

	for(int i=0;i<animation->get_track_count();i++) {



		NodePath np = animation->track_get_path(i);

		Node *node = root->get_node(np);
		if (!node) {

			path_cache.push_back(Path());
			ERR_EXPLAIN("Invalid Track Path in Animation: "+np);
			ERR_CONTINUE(!node);
		}


		Path path;

		Ref<Resource> res;

		if (np.get_subname_count()) {


			if (animation->track_get_type(i)==Animation::TYPE_TRANSFORM) {

				path_cache.push_back(Path());
				ERR_EXPLAIN("Transform tracks can't have a subpath: "+np);
				ERR_CONTINUE(animation->track_get_type(i)==Animation::TYPE_TRANSFORM);

			}

			RES res;

			for(int j=0;j<np.get_subname_count();j++) {
				res = j==0 ? node->get(np.get_subname(j)) : res->get(np.get_subname(j));
				if (res.is_null())
					break;

			}

			if (res.is_null()) {

				path_cache.push_back(Path());
				ERR_EXPLAIN("Invalid Track SubPath in Animation: "+np);
				ERR_CONTINUE(res.is_null());
			}

			path.resource=res;
			path.object=res.ptr();

		} else {


			if (animation->track_get_type(i)==Animation::TYPE_TRANSFORM) {
				StringName property = np.get_property();
				String ps = property;


				Spatial *sp = node->cast_to<Spatial>();

				if (!sp) {

					path_cache.push_back(Path());
					ERR_EXPLAIN("Transform track not of type Spatial: "+np);
					ERR_CONTINUE(!sp);
				}

				if (ps!="") {

					Skeleton *sk = node->cast_to<Skeleton>();
					if (!sk) {

						path_cache.push_back(Path());
						ERR_EXPLAIN("Property defined in Transform track, but not a Skeleton!: "+np);
						ERR_CONTINUE(!sk);
					}

					int idx = sk->find_bone(ps);
					if (idx==-1) {

						path_cache.push_back(Path());
						ERR_EXPLAIN("Property defined in Transform track, but not a Skeleton Bone!: "+np);
						ERR_CONTINUE(idx==-1);

					}

					path.bone_idx=idx;
					path.skeleton=sk;

				}

				path.spatial=sp;

			}

			path.node=node;
			path.object=node;

		}

		if (animation->track_get_type(i)==Animation::TYPE_VALUE) {

			if (np.get_property().operator String()=="") {

				path_cache.push_back(Path());
				ERR_EXPLAIN("Value Track lacks property: "+np);
				ERR_CONTINUE(np.get_property().operator String()=="");

			}

			path.property=np.get_property();

		} else if (animation->track_get_type(i)==Animation::TYPE_METHOD) {

			if (np.get_property().operator String()!="") {

				path_cache.push_back(Path());
				ERR_EXPLAIN("Method Track has property: "+np);
				ERR_CONTINUE(np.get_property().operator String()!="");

			}

		}


		path.valid=true;

		path_cache.push_back(path);

		if (!connected_nodes.has(path.node)) {
			connected_nodes.insert(path.node);
			path.node->connect("exit_tree",this,"_node_exit_tree",Node::make_binds(path.node),CONNECT_ONESHOT);
		}



	}



	cache_dirty=false;
	cache_valid=true;
}
示例#17
0
Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,int &line,String &r_err_str,ResourceParser *p_res_parser) {



/*	{
		Error err = get_token(p_stream,token,line,r_err_str);
		if (err)
			return err;
	}*/


	if (token.type==TK_CURLY_BRACKET_OPEN) {

		Dictionary d;
		Error err = _parse_dictionary(d,p_stream,line,r_err_str,p_res_parser);
		if (err)
			return err;
		value=d;
		return OK;
	} else if (token.type==TK_BRACKET_OPEN) {

		Array a;
		Error err = _parse_array(a,p_stream,line,r_err_str,p_res_parser);
		if (err)
			return err;
		value=a;
		return OK;

	} else if (token.type==TK_IDENTIFIER) {
/*
		VECTOR2,		// 5
		RECT2,
		VECTOR3,
		MATRIX32,
		PLANE,
		QUAT,			// 10
		_AABB, //sorry naming convention fail :( not like it's used often
		MATRIX3,
		TRANSFORM,

		// misc types
		COLOR,
		IMAGE,			// 15
		NODE_PATH,
		_RID,
		OBJECT,
		INPUT_EVENT,
		DICTIONARY,		// 20
		ARRAY,

		// arrays
		RAW_ARRAY,
		INT_ARRAY,
		REAL_ARRAY,
		STRING_ARRAY,	// 25
		VECTOR2_ARRAY,
		VECTOR3_ARRAY,
		COLOR_ARRAY,

		VARIANT_MAX

*/
		String id = token.value;
		if (id=="true")
			value=true;
		else if (id=="false")
			value=false;
		else if (id=="null")
			value=Variant();
		else if (id=="Vector2"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=2) {
				r_err_str="Expected 2 arguments for constructor";
			}

			value=Vector2(args[0],args[1]);
			return OK;
		} else if (id=="Rect2"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=4) {
				r_err_str="Expected 4 arguments for constructor";
			}

			value=Rect2(args[0],args[1],args[2],args[3]);
			return OK;
		} else if (id=="Vector3"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=3) {
				r_err_str="Expected 3 arguments for constructor";
			}

			value=Vector3(args[0],args[1],args[2]);
			return OK;
		} else if (id=="Matrix32"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=6) {
				r_err_str="Expected 6 arguments for constructor";
			}
			Matrix32 m;
			m[0]=Vector2(args[0],args[1]);
			m[1]=Vector2(args[2],args[3]);
			m[2]=Vector2(args[4],args[5]);
			value=m;
			return OK;
		} else if (id=="Plane") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=4) {
				r_err_str="Expected 4 arguments for constructor";
			}

			value=Plane(args[0],args[1],args[2],args[3]);
			return OK;
		} else if (id=="Quat") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=4) {
				r_err_str="Expected 4 arguments for constructor";
			}

			value=Quat(args[0],args[1],args[2],args[3]);
			return OK;

		} else if (id=="AABB"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=6) {
				r_err_str="Expected 6 arguments for constructor";
			}

			value=AABB(Vector3(args[0],args[1],args[2]),Vector3(args[3],args[4],args[5]));
			return OK;

		} else if (id=="Matrix3"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=9) {
				r_err_str="Expected 9 arguments for constructor";
			}

			value=Matrix3(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
			return OK;
		} else if (id=="Transform"){

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=12) {
				r_err_str="Expected 12 arguments for constructor";
			}

			value=Transform(Matrix3(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]),Vector3(args[9],args[10],args[11]));
			return OK;

		} else if (id=="Color") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			if (args.size()!=4) {
				r_err_str="Expected 4 arguments for constructor";
			}

			value=Color(args[0],args[1],args[2],args[3]);
			return OK;

		} else if (id=="Image") {

			//:|

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


			get_token(p_stream,token,line,r_err_str);
			if (token.type==TK_PARENTHESIS_CLOSE) {
				value=Image(); // just an Image()
				return OK;
			} else if (token.type!=TK_NUMBER) {
				r_err_str="Expected number (width)";
				return ERR_PARSE_ERROR;
			}

			get_token(p_stream,token,line,r_err_str);

			int width=token.value;
			if (token.type!=TK_COMMA) {
				r_err_str="Expected ','";
				return ERR_PARSE_ERROR;
			}

			get_token(p_stream,token,line,r_err_str);
			if (token.type!=TK_NUMBER) {
				r_err_str="Expected number (height)";
				return ERR_PARSE_ERROR;
			}

			int height=token.value;

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

			get_token(p_stream,token,line,r_err_str);
			if (token.type!=TK_NUMBER) {
				r_err_str="Expected number (mipmaps)";
				return ERR_PARSE_ERROR;
			}

			int mipmaps=token.value;

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


			get_token(p_stream,token,line,r_err_str);
			if (token.type!=TK_IDENTIFIER) {
				r_err_str="Expected identifier (format)";
				return ERR_PARSE_ERROR;
			}


			String sformat=token.value;

			Image::Format format;

			if (sformat=="GRAYSCALE") format=Image::FORMAT_GRAYSCALE;
			else if (sformat=="INTENSITY") format=Image::FORMAT_INTENSITY;
			else if (sformat=="GRAYSCALE_ALPHA") format=Image::FORMAT_GRAYSCALE_ALPHA;
			else if (sformat=="RGB") format=Image::FORMAT_RGB;
			else if (sformat=="RGBA") format=Image::FORMAT_RGBA;
			else if (sformat=="INDEXED") format=Image::FORMAT_INDEXED;
			else if (sformat=="INDEXED_ALPHA") format=Image::FORMAT_INDEXED_ALPHA;
			else if (sformat=="BC1") format=Image::FORMAT_BC1;
			else if (sformat=="BC2") format=Image::FORMAT_BC2;
			else if (sformat=="BC3") format=Image::FORMAT_BC3;
			else if (sformat=="BC4") format=Image::FORMAT_BC4;
			else if (sformat=="BC5") format=Image::FORMAT_BC5;
			else if (sformat=="PVRTC2") format=Image::FORMAT_PVRTC2;
			else if (sformat=="PVRTC2_ALPHA") format=Image::FORMAT_PVRTC2_ALPHA;
			else if (sformat=="PVRTC4") format=Image::FORMAT_PVRTC4;
			else if (sformat=="PVRTC4_ALPHA") format=Image::FORMAT_PVRTC4_ALPHA;
			else if (sformat=="ATC") format=Image::FORMAT_ATC;
			else if (sformat=="ATC_ALPHA_EXPLICIT") format=Image::FORMAT_ATC_ALPHA_EXPLICIT;
			else if (sformat=="ATC_ALPHA_INTERPOLATED") format=Image::FORMAT_ATC_ALPHA_INTERPOLATED;
			else if (sformat=="CUSTOM") format=Image::FORMAT_CUSTOM;
			else {
				r_err_str="Invalid image format: '"+sformat+"'";
				return ERR_PARSE_ERROR;
			};

			int len = Image::get_image_data_size(width,height,format,mipmaps);

			DVector<uint8_t> buffer;
			buffer.resize(len);

			if (buffer.size()!=len) {
				r_err_str="Couldn't allocate image buffer of size: "+itos(len);
			}

			{
				DVector<uint8_t>::Write w=buffer.write();

				for(int i=0;i<len;i++) {
					get_token(p_stream,token,line,r_err_str);
					if (token.type!=TK_COMMA) {
						r_err_str="Expected ','";
						return ERR_PARSE_ERROR;
					}

					get_token(p_stream,token,line,r_err_str);
					if (token.type!=TK_NUMBER) {
						r_err_str="Expected number";
						return ERR_PARSE_ERROR;
					}

					w[i]=int(token.value);

				}
			}


			Image img(width,height,mipmaps,format,buffer);

			value=img;

			return OK;


		} else if (id=="NodePath") {



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

			get_token(p_stream,token,line,r_err_str);
			if (token.type!=TK_STRING) {
				r_err_str="Expected string as argument for NodePath()";
				return ERR_PARSE_ERROR;
			}

			value=NodePath(String(token.value));

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

		} else if (id=="RID") {



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

			get_token(p_stream,token,line,r_err_str);
			if (token.type!=TK_NUMBER) {
				r_err_str="Expected number as argument";
				return ERR_PARSE_ERROR;
			}

			value=token.value;

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


			return OK;

		} else if (id=="Resource" || id=="SubResource" || id=="ExtResource") {



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


			if (p_res_parser && id=="Resource" && p_res_parser->func){

				RES res;
				Error err = p_res_parser->func(p_res_parser->userdata,p_stream,res,line,r_err_str);
				if (err)
					return err;

				value=res;

				return OK;
			} else if (p_res_parser && id=="ExtResource" && p_res_parser->ext_func){

				RES res;
				Error err = p_res_parser->ext_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
				if (err)
					return err;

				value=res;

				return OK;
			} else if (p_res_parser && id=="SubResource" && p_res_parser->sub_func){

				RES res;
				Error err = p_res_parser->sub_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
				if (err)
					return err;

				value=res;

				return OK;
			} else {

				get_token(p_stream,token,line,r_err_str);
				if (token.type==TK_STRING) {
					String path=token.value;
					RES res = ResourceLoader::load(path);
					if (res.is_null()) {
						r_err_str="Can't load resource at path: '"+path+"'.";
						return ERR_PARSE_ERROR;
					}

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

					value=res;
					return OK;

				} else {
					r_err_str="Expected string as argument for Resource().";
					return ERR_PARSE_ERROR;
				}
			}

			return OK;


		} else if (id=="InputEvent") {



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

			get_token(p_stream,token,line,r_err_str);

			if (token.type!=TK_IDENTIFIER) {
				r_err_str="Expected identifier";
				return ERR_PARSE_ERROR;
			}


			String id = token.value;

			InputEvent ie;

			if (id=="KEY") {

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

				ie.type=InputEvent::KEY;


				get_token(p_stream,token,line,r_err_str);
				if (token.type==TK_IDENTIFIER) {
					String name=token.value;
					ie.key.scancode=find_keycode(name);
				} else if (token.type==TK_NUMBER) {

					ie.key.scancode=token.value;
				} else {

					r_err_str="Expected string or integer for keycode";
					return ERR_PARSE_ERROR;
				}

				get_token(p_stream,token,line,r_err_str);

				if (token.type==TK_COMMA) {

					get_token(p_stream,token,line,r_err_str);

					if (token.type!=TK_IDENTIFIER) {
						r_err_str="Expected identifier with modifier flas";
						return ERR_PARSE_ERROR;
					}

					String mods=token.value;

					if (mods.findn("C")!=-1)
						ie.key.mod.control=true;
					if (mods.findn("A")!=-1)
						ie.key.mod.alt=true;
					if (mods.findn("S")!=-1)
						ie.key.mod.shift=true;
					if (mods.findn("M")!=-1)
						ie.key.mod.meta=true;

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

				} else if (token.type!=TK_PARENTHESIS_CLOSE) {

					r_err_str="Expected ')' or modifier flags.";
					return ERR_PARSE_ERROR;
				}


			} else if (id=="MBUTTON") {

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

				ie.type=InputEvent::MOUSE_BUTTON;

				get_token(p_stream,token,line,r_err_str);
				if (token.type!=TK_NUMBER) {
					r_err_str="Expected button index";
					return ERR_PARSE_ERROR;
				}

				ie.mouse_button.button_index = token.value;

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

			} else if (id=="JBUTTON") {

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

				ie.type=InputEvent::JOYSTICK_BUTTON;

				get_token(p_stream,token,line,r_err_str);
				if (token.type!=TK_NUMBER) {
					r_err_str="Expected button index";
					return ERR_PARSE_ERROR;
				}

				ie.joy_button.button_index = token.value;

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

			} else if (id=="JAXIS") {

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

				ie.type=InputEvent::JOYSTICK_MOTION;

				get_token(p_stream,token,line,r_err_str);
				if (token.type!=TK_NUMBER) {
					r_err_str="Expected axis index";
					return ERR_PARSE_ERROR;
				}

				ie.joy_motion.axis = token.value;

				get_token(p_stream,token,line,r_err_str);

				if (token.type!=TK_COMMA) {
					r_err_str="Expected ',' after axis index";
					return ERR_PARSE_ERROR;
				}

				get_token(p_stream,token,line,r_err_str);
				if (token.type!=TK_NUMBER) {
					r_err_str="Expected axis sign";
					return ERR_PARSE_ERROR;
				}

				ie.joy_motion.axis_value = token.value;

				get_token(p_stream,token,line,r_err_str);

				if (token.type!=TK_PARENTHESIS_CLOSE) {
					r_err_str="Expected ')' for jaxis";
					return ERR_PARSE_ERROR;
				}

			} else {

				r_err_str="Invalid input event type.";
				return ERR_PARSE_ERROR;
			}

			value=ie;

			return OK;

		} else if (id=="ByteArray") {

			Vector<uint8_t> args;
			Error err = _parse_construct<uint8_t>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			DVector<uint8_t> arr;
			{
				int len=args.size();
				arr.resize(len);
				DVector<uint8_t>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=args[i];
				}
			}

			value=arr;

			return OK;

		} else if (id=="IntArray") {

			Vector<int32_t> args;
			Error err = _parse_construct<int32_t>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			DVector<int32_t> arr;
			{
				int len=args.size();
				arr.resize(len);
				DVector<int32_t>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=int(args[i]);
				}
			}

			value=arr;

			return OK;

		} else if (id=="FloatArray") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			DVector<float> arr;
			{
				int len=args.size();
				arr.resize(len);
				DVector<float>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=args[i];
				}
			}

			value=arr;

			return OK;
		} else if (id=="StringArray") {


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

			Vector<String> cs;

			bool first=true;
			while(true) {

				if (!first) {
					get_token(p_stream,token,line,r_err_str);
					if (token.type==TK_COMMA) {
						//do none
					} else if (token.type==TK_PARENTHESIS_CLOSE) {
						break;
					} else {
						r_err_str="Expected ',' or ')'";
						return ERR_PARSE_ERROR;

					}
				}
				get_token(p_stream,token,line,r_err_str);

				if (token.type!=TK_STRING) {
					r_err_str="Expected string";					
					return ERR_PARSE_ERROR;
				}

				first=false;
				cs.push_back(token.value);
			}


			DVector<String> arr;
			{
				int len=cs.size();
				arr.resize(len);
				DVector<String>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=cs[i];
				}
			}

			value=arr;

			return OK;


		} else if (id=="Vector2Array") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			DVector<Vector2> arr;
			{
				int len=args.size()/2;
				arr.resize(len);
				DVector<Vector2>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=Vector2(args[i*2+0],args[i*2+1]);
				}
			}

			value=arr;

			return OK;

		} else if (id=="Vector3Array") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			DVector<Vector3> arr;
			{
				int len=args.size()/3;
				arr.resize(len);
				DVector<Vector3>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=Vector3(args[i*3+0],args[i*3+1],args[i*3+2]);
				}
			}

			value=arr;

			return OK;

		} else if (id=="ColorArray") {

			Vector<float> args;
			Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
			if (err)
				return err;

			DVector<Color> arr;
			{
				int len=args.size()/4;
				arr.resize(len);
				DVector<Color>::Write w = arr.write();
				for(int i=0;i<len;i++) {
					w[i]=Color(args[i*4+0],args[i*4+1],args[i*4+2],args[i*4+3]);
				}
			}

			value=arr;

			return OK;
		} else if (id=="key") { // compatibility with engine.cfg

			Vector<String> params;
			Error err = _parse_enginecfg(p_stream,params,line,r_err_str);
			if (err)
				return err;
			ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,ERR_PARSE_ERROR);

			int scode=0;

			if (params[0].is_numeric()) {
				scode=params[0].to_int();
				if (scode < 10) {
					scode=KEY_0+scode;
				}
			} else
				scode=find_keycode(params[0]);

			InputEvent ie;
			ie.type=InputEvent::KEY;
			ie.key.scancode=scode;

			if (params.size()==2) {
				String mods=params[1];
				if (mods.findn("C")!=-1)
					ie.key.mod.control=true;
				if (mods.findn("A")!=-1)
					ie.key.mod.alt=true;
				if (mods.findn("S")!=-1)
					ie.key.mod.shift=true;
				if (mods.findn("M")!=-1)
					ie.key.mod.meta=true;
			}
			value=ie;
			return OK;

		} else if (id=="mbutton") {  // compatibility with engine.cfg

			Vector<String> params;
			Error err = _parse_enginecfg(p_stream,params,line,r_err_str);
			if (err)
				return err;
			ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR);

			InputEvent ie;
			ie.type=InputEvent::MOUSE_BUTTON;
			ie.device=params[0].to_int();
			ie.mouse_button.button_index=params[1].to_int();

			value=ie;
			return OK;
		} else if (id=="jbutton") {  // compatibility with engine.cfg

			Vector<String> params;
			Error err = _parse_enginecfg(p_stream,params,line,r_err_str);
			if (err)
				return err;
			ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR);
			InputEvent ie;
			ie.type=InputEvent::JOYSTICK_BUTTON;
			ie.device=params[0].to_int();
			ie.joy_button.button_index=params[1].to_int();

			value=ie;

			return OK;
		} else if (id=="jaxis") {  // compatibility with engine.cfg

			Vector<String> params;
			Error err = _parse_enginecfg(p_stream,params,line,r_err_str);
			if (err)
				return err;
			ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR);

			InputEvent ie;
			ie.type=InputEvent::JOYSTICK_MOTION;
			ie.device=params[0].to_int();
			int axis=params[1].to_int();
			ie.joy_motion.axis=axis>>1;
			ie.joy_motion.axis_value=axis&1?1:-1;

			value= ie;

			return OK;
		} else if (id=="img") {  // compatibility with engine.cfg