]> git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3map2/convert_bsp.c
quake3/help: move away from termcap
[xonotic/netradiant.git] / tools / quake3 / q3map2 / convert_bsp.c
1 /* -------------------------------------------------------------------------------
2
3    Copyright (C) 1999-2007 id Software, Inc. and contributors.
4    For a list of contributors, see the accompanying CONTRIBUTORS file.
5
6    This file is part of GtkRadiant.
7
8    GtkRadiant is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    GtkRadiant is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GtkRadiant; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
22    -------------------------------------------------------------------------------
23
24    This code has been altered significantly from its original form, to support
25    several games based on the Quake III Arena engine, in the form of "Q3Map2."
26
27    ------------------------------------------------------------------------------- */
28
29
30
31 /* dependencies */
32 #include "q3map2.h"
33
34
35
36 /*
37    PseudoCompileBSP()
38    a stripped down ProcessModels
39  */
40 void PseudoCompileBSP( qboolean need_tree, const char *BSPFilePath, const char *surfaceFilePath ){
41         int models;
42         char modelValue[10];
43         entity_t *entity;
44         face_t *faces;
45         tree_t *tree;
46         node_t *node;
47         brush_t *brush;
48         side_t *side;
49         int i;
50
51         SetDrawSurfacesBuffer();
52         mapDrawSurfs = safe_malloc0( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS );
53         numMapDrawSurfs = 0;
54
55         BeginBSPFile();
56         models = 1;
57         for ( mapEntityNum = 0; mapEntityNum < numEntities; mapEntityNum++ )
58         {
59                 /* get entity */
60                 entity = &entities[ mapEntityNum ];
61                 if ( entity->brushes == NULL && entity->patches == NULL ) {
62                         continue;
63                 }
64
65                 if ( mapEntityNum != 0 ) {
66                         sprintf( modelValue, "*%d", models++ );
67                         SetKeyValue( entity, "model", modelValue );
68                 }
69
70                 /* process the model */
71                 Sys_FPrintf( SYS_VRB, "############### model %i ###############\n", numBSPModels );
72                 BeginModel();
73
74                 entity->firstDrawSurf = numMapDrawSurfs;
75
76                 ClearMetaTriangles();
77                 PatchMapDrawSurfs( entity );
78
79                 if ( mapEntityNum == 0 && need_tree ) {
80                         faces = MakeStructuralBSPFaceList( entities[0].brushes );
81                         tree = FaceBSP( faces );
82                         node = tree->headnode;
83                 }
84                 else
85                 {
86                         node = AllocNode();
87                         node->planenum = PLANENUM_LEAF;
88                         tree = AllocTree();
89                         tree->headnode = node;
90                 }
91
92                 /* a minimized ClipSidesIntoTree */
93                 for ( brush = entity->brushes; brush; brush = brush->next )
94                 {
95                         /* walk the brush sides */
96                         for ( i = 0; i < brush->numsides; i++ )
97                         {
98                                 /* get side */
99                                 side = &brush->sides[ i ];
100                                 if ( side->winding == NULL ) {
101                                         continue;
102                                 }
103                                 /* shader? */
104                                 if ( side->shaderInfo == NULL ) {
105                                         continue;
106                                 }
107                                 /* save this winding as a visible surface */
108                                 DrawSurfaceForSide( entity, brush, side, side->winding );
109                         }
110                 }
111
112                 if ( meta ) {
113                         ClassifyEntitySurfaces( entity );
114                         MakeEntityDecals( entity );
115                         MakeEntityMetaTriangles( entity );
116                         SmoothMetaTriangles();
117                         MergeMetaTriangles();
118                 }
119                 FilterDrawsurfsIntoTree( entity, tree );
120
121                 FilterStructuralBrushesIntoTree( entity, tree );
122                 FilterDetailBrushesIntoTree( entity, tree );
123
124                 EmitBrushes( entity->brushes, &entity->firstBrush, &entity->numBrushes );
125                 EndModel( entity, node );
126         }
127         EndBSPFile( qfalse, BSPFilePath, surfaceFilePath );
128 }
129
130 /*
131    ConvertBSPMain()
132    main argument processing function for bsp conversion
133  */
134
135 int ConvertBSPMain( int argc, char **argv ){
136         int i;
137         int ( *convertFunc )( char * );
138         game_t  *convertGame;
139         char ext[1024];
140         char BSPFilePath [ 1024 ];
141         char surfaceFilePath [ 1024 ];
142         qboolean map_allowed, force_bsp, force_map;
143
144
145         /* set default */
146         convertFunc = ConvertBSPToASE;
147         convertGame = NULL;
148         map_allowed = qfalse;
149         force_bsp = qfalse;
150         force_map = qfalse;
151
152         /* arg checking */
153         if ( argc < 2 ) {
154                 Sys_Printf( "Usage: q3map -convert [-format <ase|obj|map_bp|map>] [-shadersasbitmap|-lightmapsastexcoord|-deluxemapsastexcoord] [-readbsp|-readmap [-meta|-patchmeta]] [-v] <mapname>\n" );
155                 return 0;
156         }
157
158         /* process arguments */
159         for ( i = 1; i < ( argc - 1 ); i++ )
160         {
161                 /* -format map|ase|... */
162                 if ( !strcmp( argv[ i ],  "-format" ) ) {
163                         i++;
164                         if ( !Q_stricmp( argv[ i ], "ase" ) ) {
165                                 convertFunc = ConvertBSPToASE;
166                                 map_allowed = qfalse;
167                         }
168                         else if ( !Q_stricmp( argv[ i ], "obj" ) ) {
169                                 convertFunc = ConvertBSPToOBJ;
170                                 map_allowed = qfalse;
171                         }
172                         else if ( !Q_stricmp( argv[ i ], "map_bp" ) ) {
173                                 convertFunc = ConvertBSPToMap_BP;
174                                 map_allowed = qtrue;
175                         }
176                         else if ( !Q_stricmp( argv[ i ], "map" ) ) {
177                                 convertFunc = ConvertBSPToMap;
178                                 map_allowed = qtrue;
179                         }
180                         else
181                         {
182                                 convertGame = GetGame( argv[ i ] );
183                                 map_allowed = qfalse;
184                                 if ( convertGame == NULL ) {
185                                         Sys_FPrintf( SYS_WRN, "Unknown conversion format \"%s\". Defaulting to ASE.\n", argv[ i ] );
186                                 }
187                         }
188                 }
189                 else if ( !strcmp( argv[ i ],  "-ne" ) ) {
190                         normalEpsilon = atof( argv[ i + 1 ] );
191                         i++;
192                         Sys_Printf( "Normal epsilon set to %f\n", normalEpsilon );
193                 }
194                 else if ( !strcmp( argv[ i ],  "-de" ) ) {
195                         distanceEpsilon = atof( argv[ i + 1 ] );
196                         i++;
197                         Sys_Printf( "Distance epsilon set to %f\n", distanceEpsilon );
198                 }
199                 else if ( !strcmp( argv[ i ],  "-shaderasbitmap" ) || !strcmp( argv[ i ],  "-shadersasbitmap" ) ) {
200                         shadersAsBitmap = qtrue;
201                 }
202                 else if ( !strcmp( argv[ i ],  "-lightmapastexcoord" ) || !strcmp( argv[ i ],  "-lightmapsastexcoord" ) ) {
203                         lightmapsAsTexcoord = qtrue;
204                 }
205                 else if ( !strcmp( argv[ i ],  "-deluxemapastexcoord" ) || !strcmp( argv[ i ],  "-deluxemapsastexcoord" ) ) {
206                         lightmapsAsTexcoord = qtrue;
207                         deluxemap = qtrue;
208                 }
209                 else if ( !strcmp( argv[ i ],  "-readbsp" ) ) {
210                         force_bsp = qtrue;
211                 }
212                 else if ( !strcmp( argv[ i ],  "-readmap" ) ) {
213                         force_map = qtrue;
214                 }
215                 else if ( !strcmp( argv[ i ],  "-meta" ) ) {
216                         meta = qtrue;
217                 }
218                 else if ( !strcmp( argv[ i ],  "-patchmeta" ) ) {
219                         meta = qtrue;
220                         patchMeta = qtrue;
221                 }
222         }
223
224         LoadShaderInfo();
225
226         /* clean up map name */
227         strcpy( source, ExpandArg( argv[i] ) );
228         ExtractFileExtension( source, ext );
229
230         if ( !map_allowed && !force_map ) {
231                 force_bsp = qtrue;
232         }
233
234         if ( force_map || ( !force_bsp && !Q_stricmp( ext, "map" ) && map_allowed ) ) {
235                 if ( !map_allowed ) {
236                         Sys_FPrintf( SYS_WRN, "WARNING: the requested conversion should not be done from .map files. Compile a .bsp first.\n" );
237                 }
238                 StripExtension( source );
239                 DefaultExtension( source, ".map" );
240                 Sys_Printf( "Loading %s\n", source );
241                 LoadMapFile( source, qfalse, convertGame == NULL );
242                 sprintf( BSPFilePath, "%s.bsp", source );
243                 sprintf( surfaceFilePath, "%s.srf", source );
244                 PseudoCompileBSP( convertGame != NULL, BSPFilePath, surfaceFilePath );
245         }
246         else
247         {
248                 StripExtension( source );
249                 DefaultExtension( source, ".bsp" );
250                 Sys_Printf( "Loading %s\n", source );
251                 LoadBSPFile( source );
252                 ParseEntities();
253         }
254
255         /* bsp format convert? */
256         if ( convertGame != NULL ) {
257                 /* set global game */
258                 game = convertGame;
259
260                 /* write bsp */
261                 StripExtension( source );
262                 DefaultExtension( source, "_c.bsp" );
263                 Sys_Printf( "Writing %s\n", source );
264                 WriteBSPFile( source );
265
266                 /* return to sender */
267                 return 0;
268         }
269
270         /* normal convert */
271         return convertFunc( source );
272 }