more eol-style
[xonotic/netradiant.git] / plugins / mapxml / xmlwrite.cpp
1 //
2 // writes xml tree format from internal objects
3 //
4
5
6 #include "plugin.h"
7
8 char *str_append_token(char *str1, const char *str2)
9 {
10   char *str;
11   if(str1 != NULL)
12   {
13     str = new char[strlen(str1)+strlen(str2)+2];
14     sprintf(str, "%s %s", str1, str2);
15     delete [] str1;
16   }
17   else
18   {
19     str = new char[strlen(str2)+1];
20     strcpy(str, str2);
21   }
22   return str;
23 }
24
25 void str_from_float(char *buf, float f)
26 {
27   if(f == (int)f) sprintf(buf, "%i", (int)f);
28   else  sprintf(buf, "%f", f);
29 }
30
31 void Patch_XMLWrite(patchMesh_t *pPatch, xmlNodePtr surface)
32 {
33   char buf[16];
34   char *str;
35   int i, j;
36   xmlNodePtr node;
37
38   // write shader
39   node = xmlNewChild(surface, NULL, (xmlChar *)"shader", (xmlChar *)pPatch->pShader->getName());
40
41   // write matrix
42   str = NULL;
43   for(i=0; i<pPatch->width; i++)
44   {
45     for(j=0; j<pPatch->height; j++)
46     {
47       str_from_float(buf, pPatch->ctrl[i][j].xyz[0]);
48       str = str_append_token(str, buf);
49       str_from_float(buf, pPatch->ctrl[i][j].xyz[1]);
50       str = str_append_token(str, buf);
51       str_from_float(buf, pPatch->ctrl[i][j].xyz[2]);
52       str = str_append_token(str, buf);
53       str_from_float(buf, pPatch->ctrl[i][j].st[0]);
54       str = str_append_token(str, buf);
55       str_from_float(buf, pPatch->ctrl[i][j].st[1]);
56       str = str_append_token(str, buf);
57     }
58   }
59
60   node = xmlNewChild(surface, NULL, (xmlChar *)"matrix", (xmlChar *)str);
61   delete [] str;
62   sprintf(buf, "%i", pPatch->width);
63   xmlSetProp(node, (xmlChar *)"width", (xmlChar *)buf);
64   sprintf(buf, "%i", pPatch->height);
65   xmlSetProp(node, (xmlChar *)"height", (xmlChar *)buf);
66 }
67
68 void Face_XMLWrite (face_t *face, xmlNodePtr surface, bool bAlternateTexdef = false)
69 {
70   char buf[16];
71   xmlNodePtr node;
72   int i, j;
73   char *str;
74  
75   // write shader
76   node = xmlNewChild(surface, NULL, (xmlChar *)"shader", (xmlChar *)face->texdef.GetName());
77
78   // write planepts
79   str = NULL;
80   for (i=0 ; i<3 ; i++)
81         {
82                 for (j=0 ; j<3 ; j++)
83                 {
84       str_from_float(buf, face->planepts[i][j]);
85       str = str_append_token(str, buf);
86                 }
87   }
88
89   node = xmlNewChild(surface, NULL, (xmlChar *)"planepts", (xmlChar *)str);
90   delete [] str;
91
92   if(!bAlternateTexdef)
93   {
94     // write texdef
95     sprintf(buf, "%i", (int)face->texdef.shift[0]);
96     str = str_append_token(NULL, buf);
97     sprintf(buf, "%i", (int)face->texdef.shift[1]);
98     str = str_append_token(str, buf);
99     sprintf(buf, "%i", (int)face->texdef.rotate);
100     str = str_append_token(str, buf);
101     sprintf(buf, "%f", face->texdef.scale[0]);
102     str = str_append_token(str, buf);
103     sprintf(buf, "%f", face->texdef.scale[1]);
104     str = str_append_token(str, buf);
105
106     node = xmlNewChild(surface, NULL, (xmlChar *)"texdef", (xmlChar *)str);
107     delete [] str;
108   }
109   else
110   {
111     // write matrix texdef
112     str = NULL;
113     for (i=0 ; i<2 ; i++)
114           {
115                   for (j=0 ; j<3 ; j++)
116                   {
117         str_from_float(buf, face->brushprimit_texdef.coords[i][j]);
118         str = str_append_token(str, buf);
119                   }
120     }
121     node = xmlNewChild(surface, NULL, (xmlChar *)"bpmatrix", (xmlChar *)str);
122     delete [] str;
123   }
124
125   // write flags
126   sprintf(buf, "%i", face->texdef.contents);
127   str = str_append_token(NULL, buf);
128   sprintf(buf, "%i", face->texdef.flags);
129   str = str_append_token(str, buf);
130   sprintf(buf, "%i", face->texdef.value);
131   str = str_append_token(str, buf);
132
133   node = xmlNewChild(surface, NULL, (xmlChar *)"flags", (xmlChar *)str);
134   delete [] str;
135 }
136
137 void Brush_XMLWrite (brush_t *brush, xmlNodePtr primitive)
138 {
139   xmlNodePtr node;
140
141   for(face_t *face = brush->brush_faces; face != NULL; face = face->next)
142   {
143     node = xmlNewChild(primitive, NULL, (xmlChar *)"plane", NULL);
144     Face_XMLWrite (face, node, brush->bBrushDef);
145   }
146 }
147
148 void Epair_XMLWrite(epair_t *pEpair, xmlNodePtr epair)
149 {
150   xmlSetProp(epair, (xmlChar *)"key", (xmlChar *)pEpair->key);
151   xmlSetProp(epair, (xmlChar *)"value", (xmlChar *)pEpair->value);
152 }
153
154 void Entity_XMLWrite(entity_t *pEntity, xmlNodePtr entity)
155 {
156   brush_t *pBrush;
157   epair_t *pEpair;
158   xmlNodePtr node;
159
160   CPtrArray *brushes = (CPtrArray*)pEntity->pData;
161  
162   for(pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next)
163   {
164     node = xmlNewChild(entity, NULL, (xmlChar *)"epair", NULL);
165     Epair_XMLWrite(pEpair, node);
166   }
167
168   for(int i=0; i<brushes->GetSize(); i++)
169   {
170     pBrush = (brush_t*)brushes->GetAt(i);
171
172     if(pBrush->patchBrush)
173     {
174       node = xmlNewChild(entity, NULL, (xmlChar *)"patch", NULL);
175       Patch_XMLWrite(pBrush->pPatch, node);
176     }
177     else
178     {
179       node = xmlNewChild(entity, NULL, (xmlChar *)"brush", NULL);
180       Brush_XMLWrite(pBrush, node);
181     }
182   }
183 }
184
185 void Map_XMLWrite (CPtrArray *map, xmlNodePtr map_node)
186 {
187   entity_t *pEntity;
188   xmlNodePtr node;
189
190   for(int i=0; i<map->GetSize(); i++)
191   {
192     pEntity = (entity_t*)map->GetAt(i);
193
194     node = xmlNewChild(map_node, NULL, (xmlChar *)"entity", NULL);
195     Entity_XMLWrite(pEntity, node);
196   }
197 }
198
199 void Map_Write (CPtrArray *map, IDataStream *out)
200 {
201   xmlChar* buf;
202   int len;
203   
204   xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0");
205   xmlCreateIntSubset(doc, (xmlChar *)"mapq3", NULL, (xmlChar *)"mapq3.dtd");
206   doc->children->next = xmlNewDocNode(doc, NULL, (xmlChar *)"mapq3", NULL);
207
208   Map_XMLWrite(map, doc->children->next);
209
210   // xmlDocDumpMemory(doc, &buf, &len);
211   xmlDocDumpFormatMemory(doc, &buf, &len, 1);
212   xmlFreeDoc(doc);
213
214   out->Write(buf, len);
215
216   xmlFree(buf);
217 }