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