-//\r
-// writes xml tree format from internal objects\r
-//\r
-\r
-\r
-#include "plugin.h"\r
-\r
-char *str_append_token(char *str1, const char *str2)\r
-{\r
- char *str;\r
- if(str1 != NULL)\r
- {\r
- str = new char[strlen(str1)+strlen(str2)+2];\r
- sprintf(str, "%s %s", str1, str2);\r
- delete [] str1;\r
- }\r
- else\r
- {\r
- str = new char[strlen(str2)+1];\r
- strcpy(str, str2);\r
- }\r
- return str;\r
-}\r
-\r
-void str_from_float(char *buf, float f)\r
-{\r
- if(f == (int)f) sprintf(buf, "%i", (int)f);\r
- else sprintf(buf, "%f", f);\r
-}\r
-\r
-void Patch_XMLWrite(patchMesh_t *pPatch, xmlNodePtr surface)\r
-{\r
- char buf[16];\r
- char *str;\r
- int i, j;\r
- xmlNodePtr node;\r
-\r
- // write shader\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"shader", (xmlChar *)pPatch->pShader->getName());\r
-\r
- // write matrix\r
- str = NULL;\r
- for(i=0; i<pPatch->width; i++)\r
- {\r
- for(j=0; j<pPatch->height; j++)\r
- {\r
- str_from_float(buf, pPatch->ctrl[i][j].xyz[0]);\r
- str = str_append_token(str, buf);\r
- str_from_float(buf, pPatch->ctrl[i][j].xyz[1]);\r
- str = str_append_token(str, buf);\r
- str_from_float(buf, pPatch->ctrl[i][j].xyz[2]);\r
- str = str_append_token(str, buf);\r
- str_from_float(buf, pPatch->ctrl[i][j].st[0]);\r
- str = str_append_token(str, buf);\r
- str_from_float(buf, pPatch->ctrl[i][j].st[1]);\r
- str = str_append_token(str, buf);\r
- }\r
- }\r
-\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"matrix", (xmlChar *)str);\r
- delete [] str;\r
- sprintf(buf, "%i", pPatch->width);\r
- xmlSetProp(node, (xmlChar *)"width", (xmlChar *)buf);\r
- sprintf(buf, "%i", pPatch->height);\r
- xmlSetProp(node, (xmlChar *)"height", (xmlChar *)buf);\r
-}\r
-\r
-void Face_XMLWrite (face_t *face, xmlNodePtr surface, bool bAlternateTexdef = false)\r
-{\r
- char buf[16];\r
- xmlNodePtr node;\r
- int i, j;\r
- char *str;\r
- \r
- // write shader\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"shader", (xmlChar *)face->texdef.GetName());\r
-\r
- // write planepts\r
- str = NULL;\r
- for (i=0 ; i<3 ; i++)\r
- {\r
- for (j=0 ; j<3 ; j++)\r
- {\r
- str_from_float(buf, face->planepts[i][j]);\r
- str = str_append_token(str, buf);\r
- }\r
- }\r
-\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"planepts", (xmlChar *)str);\r
- delete [] str;\r
-\r
- if(!bAlternateTexdef)\r
- {\r
- // write texdef\r
- sprintf(buf, "%i", (int)face->texdef.shift[0]);\r
- str = str_append_token(NULL, buf);\r
- sprintf(buf, "%i", (int)face->texdef.shift[1]);\r
- str = str_append_token(str, buf);\r
- sprintf(buf, "%i", (int)face->texdef.rotate);\r
- str = str_append_token(str, buf);\r
- sprintf(buf, "%f", face->texdef.scale[0]);\r
- str = str_append_token(str, buf);\r
- sprintf(buf, "%f", face->texdef.scale[1]);\r
- str = str_append_token(str, buf);\r
-\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"texdef", (xmlChar *)str);\r
- delete [] str;\r
- }\r
- else\r
- {\r
- // write matrix texdef\r
- str = NULL;\r
- for (i=0 ; i<2 ; i++)\r
- {\r
- for (j=0 ; j<3 ; j++)\r
- {\r
- str_from_float(buf, face->brushprimit_texdef.coords[i][j]);\r
- str = str_append_token(str, buf);\r
- }\r
- }\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"bpmatrix", (xmlChar *)str);\r
- delete [] str;\r
- }\r
-\r
- // write flags\r
- sprintf(buf, "%i", face->texdef.contents);\r
- str = str_append_token(NULL, buf);\r
- sprintf(buf, "%i", face->texdef.flags);\r
- str = str_append_token(str, buf);\r
- sprintf(buf, "%i", face->texdef.value);\r
- str = str_append_token(str, buf);\r
-\r
- node = xmlNewChild(surface, NULL, (xmlChar *)"flags", (xmlChar *)str);\r
- delete [] str;\r
-}\r
-\r
-void Brush_XMLWrite (brush_t *brush, xmlNodePtr primitive)\r
-{\r
- xmlNodePtr node;\r
-\r
- for(face_t *face = brush->brush_faces; face != NULL; face = face->next)\r
- {\r
- node = xmlNewChild(primitive, NULL, (xmlChar *)"plane", NULL);\r
- Face_XMLWrite (face, node, brush->bBrushDef);\r
- }\r
-}\r
-\r
-void Epair_XMLWrite(epair_t *pEpair, xmlNodePtr epair)\r
-{\r
- xmlSetProp(epair, (xmlChar *)"key", (xmlChar *)pEpair->key);\r
- xmlSetProp(epair, (xmlChar *)"value", (xmlChar *)pEpair->value);\r
-}\r
-\r
-void Entity_XMLWrite(entity_t *pEntity, xmlNodePtr entity)\r
-{\r
- brush_t *pBrush;\r
- epair_t *pEpair;\r
- xmlNodePtr node;\r
-\r
- CPtrArray *brushes = (CPtrArray*)pEntity->pData;\r
- \r
- for(pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next)\r
- {\r
- node = xmlNewChild(entity, NULL, (xmlChar *)"epair", NULL);\r
- Epair_XMLWrite(pEpair, node);\r
- }\r
-\r
- for(int i=0; i<brushes->GetSize(); i++)\r
- {\r
- pBrush = (brush_t*)brushes->GetAt(i);\r
-\r
- if(pBrush->patchBrush)\r
- {\r
- node = xmlNewChild(entity, NULL, (xmlChar *)"patch", NULL);\r
- Patch_XMLWrite(pBrush->pPatch, node);\r
- }\r
- else\r
- {\r
- node = xmlNewChild(entity, NULL, (xmlChar *)"brush", NULL);\r
- Brush_XMLWrite(pBrush, node);\r
- }\r
- }\r
-}\r
-\r
-void Map_XMLWrite (CPtrArray *map, xmlNodePtr map_node)\r
-{\r
- entity_t *pEntity;\r
- xmlNodePtr node;\r
-\r
- for(int i=0; i<map->GetSize(); i++)\r
- {\r
- pEntity = (entity_t*)map->GetAt(i);\r
-\r
- node = xmlNewChild(map_node, NULL, (xmlChar *)"entity", NULL);\r
- Entity_XMLWrite(pEntity, node);\r
- }\r
-}\r
-\r
-void Map_Write (CPtrArray *map, IDataStream *out)\r
-{\r
- xmlChar* buf;\r
- int len;\r
- \r
- xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0");\r
- xmlCreateIntSubset(doc, (xmlChar *)"mapq3", NULL, (xmlChar *)"mapq3.dtd");\r
- doc->children->next = xmlNewDocNode(doc, NULL, (xmlChar *)"mapq3", NULL);\r
-\r
- Map_XMLWrite(map, doc->children->next);\r
-\r
- // xmlDocDumpMemory(doc, &buf, &len);\r
- xmlDocDumpFormatMemory(doc, &buf, &len, 1);\r
- xmlFreeDoc(doc);\r
-\r
- out->Write(buf, len);\r
-\r
- xmlFree(buf);\r
-}\r
+/*
+ Copyright (C) 2001-2006, William Joseph.
+ All Rights Reserved.
+
+ This file is part of GtkRadiant.
+
+ GtkRadiant is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ GtkRadiant is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GtkRadiant; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+//
+// writes xml tree format from internal objects
+//
+
+#include "xmlwrite.h"
+
+#include "xml/xmlwriter.h"
+#include "scenelib.h"
+#include "entityxml.h"
+
+inline XMLExporter* Node_getXMLExporter( scene::Node& node ){
+ return NodeTypeCast<XMLExporter>::cast( node );
+}
+
+
+class write_all : public scene::Traversable::Walker
+{
+XMLImporter& m_importer;
+public:
+write_all( XMLImporter& importer ) : m_importer( importer ){
+}
+bool pre( scene::Node& node ) const {
+ Entity* entity = Node_getEntity( node );
+ if ( entity != 0 ) {
+ m_importer.write( "\n", 1 );
+ StaticElement element( "entity" );
+ m_importer.pushElement( element );
+ entity_export exporter( *entity );
+ exporter.exportXML( m_importer );
+ }
+ else
+ {
+ XMLExporter* exporter = Node_getXMLExporter( node );
+ if ( exporter != 0 ) {
+ m_importer.write( "\n", 1 );
+ exporter->exportXML( m_importer );
+ m_importer.write( "\n", 1 );
+ }
+ }
+ return true;
+}
+void post( scene::Node& node ) const {
+ if ( Node_getEntity( node ) != 0 ) {
+ m_importer.write( "\n", 1 );
+ m_importer.popElement( "entity" );
+ }
+}
+};
+
+void Map_Write( scene::Node& root, GraphTraversalFunc traverse, TextOutputStream& out ){
+ XMLStreamWriter writer( out );
+ writer.write( "\n", 1 );
+ {
+ StaticElement element( "mapdoom3" );
+ writer.pushElement( element );
+
+ traverse( root, write_all( writer ) );
+
+ writer.write( "\n", 1 );
+ writer.popElement( element.name() );
+ }
+}