diff --git a/core/io/export_data.h b/core/io/export_data.h index 17ee60f3391..1e1941bad3d 100644 --- a/core/io/export_data.h +++ b/core/io/export_data.h @@ -32,6 +32,7 @@ struct ExportData { struct NodeData { bool text_data; + bool instanced; String name; String type; String instance; @@ -52,7 +53,7 @@ struct ExportData { List properties; - NodeData() { parent_int=0; owner_int=0; text_data=true; } + NodeData() { parent_int=0; owner_int=0; text_data=true; instanced=false;} }; Vector nodes; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 2b6cfe0514e..16bcda39825 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -467,10 +467,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v,bool p_for_exp } 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;iget_32(); + Dictionary d(len&0x80000000); //last bit means shared + len&=0x7FFFFFFF; + for(uint32_t i=0;iget_32(); - Array a(len&0x80000000); //last bit means shared - len&=0x7FFFFFFF; + 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=0) { @@ -473,7 +491,6 @@ void EditorExportGodot3::_unpack_packed_scene(ExportData &resource) { node_data.groups.push_back(names[group_name]); } - resource.nodes.push_back(node_data); } } @@ -549,7 +566,14 @@ void EditorExportGodot3::_pack_packed_scene(ExportData &resource) { node_data.push_back(node.parent_int); node_data.push_back(node.owner_int); - node_data.push_back(_pack_name(node.type)); + if (node.instanced) { + node_data.push_back(0x7FFFFFFF); + } else { + int name = _pack_name(node.type); + print_line("packing type: "+String(node.type)+" goes to name "+itos(name)); + node_data.push_back(name); + } + node_data.push_back(_pack_name(node.name)); int instance=-1; if (node.instance!=String()) { @@ -597,7 +621,7 @@ void EditorExportGodot3::_pack_packed_scene(ExportData &resource) { } } - d["connections"]=connections; + d["conns"]=connections; Array np; for(int i=0;i data = img.get_data(); + DVector data = img.get_data(); int len = data.size(); - PoolVector::Read r = data.read(); + DVector::Read r = data.read(); const uint8_t *ptr=r.ptr(); for (int i=0;istore_8(0); //pad to 32 + } + +} + +static void save_unicode_string(const String& p_string,FileAccess *f,bool p_hi_bit=false) { + + + CharString utf8 = p_string.utf8(); + f->store_32(uint32_t(utf8.length()+1) | (p_hi_bit?0x80000000:0)); + f->store_buffer((const uint8_t*)utf8.get_data(),utf8.length()+1); +} + +void EditorExportGodot3::_save_binary_property(const Variant& p_property,FileAccess *f) { + + 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(int32_t(val)); + + + } break; + case Variant::REAL: { + + f->store_32(VARIANT_REAL); + f->store_real(p_property); + + } break; + case Variant::STRING: { + + String str=p_property; + if (str.begins_with("@RESLOCAL:")) { + f->store_32(VARIANT_OBJECT); + f->store_32(OBJECT_INTERNAL_RESOURCE); + f->store_32(str.get_slice(":",1).to_int()); + print_line("SAVE RES LOCAL: "+itos(str.get_slice(":",1).to_int())); + } else if (str.begins_with("@RESEXTERNAL:")) { + f->store_32(VARIANT_OBJECT); + f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX); + f->store_32(str.get_slice(":",1).to_int()); + print_line("SAVE RES EXTERNAL: "+itos(str.get_slice(":",1).to_int())); + } else { + + f->store_32(VARIANT_STRING); + save_unicode_string(str,f); + } + } 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); + Rect3 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; + } + + f->store_32(IMAGE_ENCODING_RAW); + + f->store_32(val.get_width()); + f->store_32(val.get_height()); + f->store_32(val.get_mipmaps()?1:0); + switch(val.get_format()) { + case Image::FORMAT_GRAYSCALE: f->store_32(IMAGE_FORMAT_L8 ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255 + case Image::FORMAT_INTENSITY: f->store_32(IMAGE_FORMAT_L8 ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255 + case Image::FORMAT_GRAYSCALE_ALPHA: f->store_32(IMAGE_FORMAT_LA8 ); 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_RGB8 ); 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_RGBA8 ); 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_BC1: f->store_32(IMAGE_FORMAT_DXT1 ); break; // DXT1 + case Image::FORMAT_BC2: f->store_32(IMAGE_FORMAT_DXT3 ); break; // DXT3 + case Image::FORMAT_BC3: f->store_32(IMAGE_FORMAT_DXT5 ); break; // DXT5 + case Image::FORMAT_BC4: f->store_32(IMAGE_FORMAT_ATI1 ); break; // ATI1 + case Image::FORMAT_BC5: f->store_32(IMAGE_FORMAT_ATI2 ); break; // ATI2 + case Image::FORMAT_PVRTC2: f->store_32(IMAGE_FORMAT_PVRTC2 ); break; + case Image::FORMAT_PVRTC2_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC2A ); break; + case Image::FORMAT_PVRTC4: f->store_32(IMAGE_FORMAT_PVRTC4 ); break; + case Image::FORMAT_PVRTC4_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC4A ); break; + case Image::FORMAT_ETC: f->store_32(IMAGE_FORMAT_ETC ); break; // regular ETC: f->store_32(IMAGE_FORMAT_ ); break; no transparency + default: f->store_32(IMAGE_FORMAT_L8 ); break; + } + + int dlen = val.get_data().size(); + f->store_32(dlen); + DVector::Read r = val.get_data().read(); + f->store_buffer(r.ptr(),dlen); + _pad_buffer(dlen,f); + + } 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;istore_32(VARIANT_RID); + WARN_PRINT("Can't save RIDs"); + RID val = p_property; + f->store_32(val.get_id()); + } break; + case Variant::OBJECT: { + + ERR_FAIL(); + + + } break; + case Variant::INPUT_EVENT: { + + f->store_32(VARIANT_INPUT_EVENT); + InputEvent event=p_property; + f->store_32(0); //event type none, nothing else suported for now. + + } break; + case Variant::DICTIONARY: { + + f->store_32(VARIANT_DICTIONARY); + Dictionary d = p_property; + f->store_32(uint32_t(d.size())); + + List keys; + d.get_key_list(&keys); + + for(List::Element *E=keys.front();E;E=E->next()) { + + /* + if (!_check_type(dict[E->get()])) + continue; + */ + + _save_binary_property(E->get(),f); + _save_binary_property(d[E->get()],f); + } + + + } break; + case Variant::ARRAY: { + + f->store_32(VARIANT_ARRAY); + Array a=p_property; + f->store_32(uint32_t(a.size())); + for(int i=0;istore_32(VARIANT_RAW_ARRAY); + DVector arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + f->store_buffer(r.ptr(),len); + _pad_buffer(len,f); + + } break; + case Variant::INT_ARRAY: { + + f->store_32(VARIANT_INT_ARRAY); + DVector arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + for(int i=0;istore_32(r[i]); + + } break; + case Variant::REAL_ARRAY: { + + f->store_32(VARIANT_REAL_ARRAY); + DVector arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + for(int i=0;istore_real(r[i]); + } + + } break; + case Variant::STRING_ARRAY: { + + f->store_32(VARIANT_STRING_ARRAY); + DVector arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + for(int i=0;istore_32(VARIANT_VECTOR3_ARRAY); + DVector arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + for(int i=0;istore_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 arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + for(int i=0;istore_real(r[i].x); + f->store_real(r[i].y); + } + + } break; + case Variant::COLOR_ARRAY: { + + f->store_32(VARIANT_COLOR_ARRAY); + DVector arr = p_property; + int len=arr.size(); + f->store_32(len); + DVector::Read r = arr.read(); + for(int i=0;istore_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(); + } + } +} void EditorExportGodot3::_save_binary(const String& p_path,ExportData &resource) { + FileAccessRef f = FileAccess::open(p_path,FileAccess::WRITE); + ERR_FAIL_COND(!f.operator ->()); + //save header compressed + static const uint8_t header[4]={'R','S','R','C'}; + f->store_buffer(header,4); + f->store_32(0); + + f->store_32(0); //64 bits file, false for now + f->store_32(3);//major + f->store_32(0); //minor + f->store_32(2); //format version (2 is for 3.0) + + + //f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed + save_unicode_string(resource.resources[resource.resources.size()-1].type,f.operator->()); + for(int i=0;i<16;i++) + f->store_32(0); // unused + + f->store_32(0); //no names saved + + f->store_32(resource.dependencies.size()); //amount of external resources + + for (Map::Element *E=resource.dependencies.front();E;E=E->next()) { + + save_unicode_string(E->get().type,f.operator->()); + save_unicode_string(E->get().path,f.operator->()); + } + + // save internal resource table + Vector ofs_pos; + f->store_32(resource.resources.size()); //amount of internal resources + for(int i=0;i()); + ofs_pos.push_back(f->get_pos()); + f->store_64(0); + } + + Vector ofs_table; +// int saved_idx=0; + //now actually save the resources + + for(int i=0;iget_pos()); + save_unicode_string(resource.resources[i].type,f.operator->()); + f->store_32(resource.resources[i].properties.size()); + + + for( List::Element *E=resource.resources[i].properties.front();E;E=E->next() ) { + + + save_unicode_string(E->get().name,f.operator->(),true); + _save_binary_property(E->get().value,f.operator->()); + } + + + } + + for(int i=0;iseek(ofs_pos[i]); + f->store_64(ofs_table[i]); + } + + f->seek_end(); + + + f->store_buffer((const uint8_t*)"RSRC",4); //magic at end + + ERR_FAIL_COND(f->get_error()!=OK); } @@ -1184,6 +1759,22 @@ void EditorExportGodot3::_save_config(const String &p_path) { String main_scene = Globals::get_singleton()->get("application/main_scene"); f->store_line("main_scene=\""+_replace_resource(main_scene).c_escape()+"\""); + List props; + Globals::get_singleton()->get_property_list(&props); + + f->store_line("[input]\n"); + + for (List::Element *E=props.front();E;E=E->next()) { + + if (!E->get().name.begins_with("input/")) + continue; + + String prop; + _get_property_as_text(Globals::get_singleton()->get(E->get().name),prop); + String what = E->get().name.get_slice("/",1); + f->store_line(what+"="+prop); + } + } diff --git a/tools/editor/editor_export_godot3.h b/tools/editor/editor_export_godot3.h index 579198a43bb..5e21c9edd96 100644 --- a/tools/editor/editor_export_godot3.h +++ b/tools/editor/editor_export_godot3.h @@ -46,6 +46,9 @@ class EditorExportGodot3 { Error _get_property_as_text(const Variant& p_variant,String&p_string); void _save_text(const String& p_path,ExportData &resource); + + void _save_binary_property(const Variant& p_property,FileAccess *f); + void _save_binary(const String& p_path,ExportData &resource); void _save_config(const String &p_path);