]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/map/write.cpp
centered about on parent window
[xonotic/netradiant.git] / plugins / map / write.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 //
23 // writes quake3 map format from internal objects
24 //
25
26 static int g_count_entities;
27 static int g_count_brushes;
28
29 #include "plugin.h"
30 extern int g_MapVersion;
31
32 void Float_Write( float data, IDataStream *out ){
33         if ( data == (int)data ) {
34                 out->printf( "%i ", (int)data );
35         }
36         else{
37                 out->printf( "%f ", data );
38         }
39 }
40
41 void Patch_Write( patchMesh_t *pPatch, IDataStream *out ){
42         int i, j;
43         const char *str;
44
45         // write shader name and matrix dimensions
46         str = pPatch->pShader->getName();
47         if ( strchr( str, ' ' ) ) {
48                 Sys_FPrintf( SYS_WRN, "WARNING: Patch_Write: shader names with spaces are not allowed, ignoring '%s'\n", str );
49                 str = SHADER_NOT_FOUND;
50         }
51         if ( !strncmp( str, "textures/", 9 ) ) {
52                 str += 9;
53         }
54         out->printf( "patchDef2\n{\n%s\n( %i %i 0 0 0 )\n",
55                                  str, pPatch->width, pPatch->height );
56
57         // write matrix
58         out->printf( "(\n" );
59         for ( i = 0; i < pPatch->width; i++ )
60         {
61                 out->printf( "( " );
62                 for ( j = 0; j < pPatch->height; j++ )
63                 {
64                         out->printf( "( " );
65
66                         Float_Write( pPatch->ctrl[i][j].xyz[0], out );
67                         Float_Write( pPatch->ctrl[i][j].xyz[1], out );
68                         Float_Write( pPatch->ctrl[i][j].xyz[2], out );
69                         Float_Write( pPatch->ctrl[i][j].st[0], out );
70                         Float_Write( pPatch->ctrl[i][j].st[1], out );
71
72                         out->printf( ") " );
73                 }
74                 out->printf( ")\n" );
75         }
76         out->printf( ")\n}\n" );
77 }
78
79 void Face_Write( face_t *face, IDataStream *out, bool bAlternateTexdef = false ){
80         int i, j;
81         const char *str;
82
83         // write planepts
84         for ( i = 0; i < 3; i++ )
85         {
86                 out->printf( "( " );
87                 for ( j = 0; j < 3; j++ )
88                 {
89                         Float_Write( face->planepts[i][j], out );
90                 }
91                 out->printf( ") " );
92         }
93
94         if ( bAlternateTexdef ) {
95                 // write alternate texdef
96                 out->printf( "( ( " );
97                 for ( i = 0; i < 3; i++ )
98                         Float_Write( face->brushprimit_texdef.coords[0][i], out );
99                 out->printf( ") ( " );
100                 for ( i = 0; i < 3; i++ )
101                         Float_Write( face->brushprimit_texdef.coords[1][i], out );
102                 out->printf( ") ) " );
103         }
104
105         // write shader name
106         str = face->texdef.GetName();
107         if ( strchr( str, ' ' ) ) {
108                 Sys_FPrintf( SYS_WRN, "WARNING: Face_Write: shader names with spaces are not allowed, ignoring '%s'\n", str );
109                 str = SHADER_NOT_FOUND;
110         }
111         if ( !strncmp( str, "textures/", 9 ) ) {
112                 str += 9;
113         }
114
115         // Strip all remaining paths.
116         // FIXME: Hydra - this is actually a HalfLife specific bit, not Q2 map format specific.
117         if ( g_MapVersion == MAPVERSION_HL ) {
118                 char *pos;
119                 while ( ( pos = (char*)strchr( str, '/' ) ) != NULL ) {
120                         str = pos + 1; // to speed optimize, change the "while" to an "if"
121                 }
122         }
123         out->printf( "%s ", str );
124
125         if ( !bAlternateTexdef ) {
126                 // write texdef
127                 out->printf( "%i %i %i %f %f ",
128                                          (int)face->texdef.shift[0],
129                                          (int)face->texdef.shift[1],
130                                          (int)face->texdef.rotate,
131                                          face->texdef.scale[0],
132                                          face->texdef.scale[1] );
133         }
134
135         if ( g_MapVersion == MAPVERSION_Q3 ) {
136                 // write surface flags
137                 out->printf( "%i %i %i\n",
138                                          face->texdef.contents,
139                                          face->texdef.flags,
140                                          face->texdef.value );
141         }
142
143         if ( ( g_MapVersion == MAPVERSION_HL ) || ( g_MapVersion == MAPVERSION_Q2 ) ) {
144                 // write surface flags if non-zero values.
145                 if ( face->texdef.contents || face->texdef.flags || face->texdef.value ) {
146                         out->printf( "%i %i %i\n",
147                                                  face->texdef.contents,
148                                                  face->texdef.flags,
149                                                  face->texdef.value );
150                 }
151                 else
152                 {
153                         out->printf( "\n" );
154                 }
155         }
156
157 }
158
159 void Primitive_Write( brush_t *pBrush, IDataStream *out ){
160         if ( ( g_MapVersion == MAPVERSION_Q2 ) && ( pBrush->patchBrush ) ) {
161                 Sys_FPrintf( SYS_WRN, "WARNING: Primitive_Write: Patches are not supported in Quake2, ignoring Brush %d\n", g_count_brushes++ );
162         }
163         else
164         {
165                 out->printf( "// brush %i\n", g_count_brushes++ );
166                 out->printf( "{\n" );
167                 if ( pBrush->patchBrush ) {
168                         Patch_Write( pBrush->pPatch, out );
169                 }
170                 else if ( pBrush->bBrushDef ) {
171                         out->printf( "brushDef\n{\n" );
172                         for ( face_t *face = pBrush->brush_faces; face != NULL; face = face->next )
173                                 Face_Write( face, out, true );
174                         out->printf( "}\n" );
175                 }
176                 else{
177                         for ( face_t *face = pBrush->brush_faces; face != NULL; face = face->next )
178                                 Face_Write( face, out );
179                 }
180                 out->printf( "}\n" );
181         }
182 }
183
184 void Entity_Write( entity_t *pEntity, IDataStream *out ){
185         epair_t *pEpair;
186         CPtrArray *brushes = (CPtrArray*)pEntity->pData;
187         out->printf( "// entity %i\n", g_count_entities++ );
188         out->printf( "{\n" );
189         for ( pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next )
190                 out->printf( "\"%s\" \"%s\"\n", pEpair->key, pEpair->value );
191         g_count_brushes = 0;
192         for ( int i = 0; i < brushes->GetSize(); i++ )
193                 Primitive_Write( (brush_t*)brushes->GetAt( i ), out );
194         out->printf( "}\n" );
195 }
196
197 void Map_Write( CPtrArray *map, IDataStream *out ){
198         g_count_entities = 0;
199         for ( int i = 0; i < map->GetSize(); i++ )
200                 Entity_Write( (entity_t*)map->GetAt( i ), out );
201 }
202
203 void Map_WriteQ3( CPtrArray *map, IDataStream *out ){
204         g_MapVersion = MAPVERSION_Q3;
205         Map_Write( map,out );
206 }
207
208 void Map_WriteHL( CPtrArray *map, IDataStream *out ){
209         g_MapVersion = MAPVERSION_HL;
210         Map_Write( map,out );
211 }
212
213 void Map_WriteQ2( CPtrArray *map, IDataStream *out ){
214         g_MapVersion = MAPVERSION_Q2;
215         Map_Write( map,out );
216 }