1 /* -------------------------------------------------------------------------------
3 Copyright (C) 1999-2007 id Software, Inc. and contributors.
4 For a list of contributors, see the accompanying CONTRIBUTORS file.
6 This file is part of GtkRadiant.
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.
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.
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
22 -------------------------------------------------------------------------------
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."
27 ------------------------------------------------------------------------------- */
37 AnalyzeBSPMain() - ydnar
38 analyzes a Quake engine BSP file
41 typedef struct abspHeader_s
46 bspLump_t lumps[ 1 ]; /* unknown size */
50 typedef struct abspLumpTest_s
57 int AnalyzeBSPMain( int argc, char **argv ){
59 int size, i, version, offset, length, lumpInt, count;
63 char lumpString[ 1024 ], source[ 1024 ];
64 qboolean lumpSwap = qfalse;
65 abspLumpTest_t *lumpTest;
66 static abspLumpTest_t lumpTests[] =
68 { sizeof( bspPlane_t ), 6, "IBSP LUMP_PLANES" },
69 { sizeof( bspBrush_t ), 1, "IBSP LUMP_BRUSHES" },
70 { 8, 6, "IBSP LUMP_BRUSHSIDES" },
71 { sizeof( bspBrushSide_t ), 6, "RBSP LUMP_BRUSHSIDES" },
72 { sizeof( bspModel_t ), 1, "IBSP LUMP_MODELS" },
73 { sizeof( bspNode_t ), 2, "IBSP LUMP_NODES" },
74 { sizeof( bspLeaf_t ), 1, "IBSP LUMP_LEAFS" },
75 { 104, 3, "IBSP LUMP_DRAWSURFS" },
76 { 44, 3, "IBSP LUMP_DRAWVERTS" },
77 { 4, 6, "IBSP LUMP_DRAWINDEXES" },
78 { 128 * 128 * 3, 1, "IBSP LUMP_LIGHTMAPS" },
79 { 256 * 256 * 3, 1, "IBSP LUMP_LIGHTMAPS (256 x 256)" },
80 { 512 * 512 * 3, 1, "IBSP LUMP_LIGHTMAPS (512 x 512)" },
87 Sys_Printf( "Usage: q3map -analyze [-lumpswap] [-v] <mapname>\n" );
91 /* process arguments */
92 for ( i = 1; i < ( argc - 1 ); i++ )
94 /* -format map|ase|... */
95 if ( !strcmp( argv[ i ], "-lumpswap" ) ) {
96 Sys_Printf( "Swapped lump structs enabled\n" );
101 /* clean up map name */
102 strcpy( source, ExpandArg( argv[ i ] ) );
103 Sys_Printf( "Loading %s\n", source );
106 size = LoadFile( source, (void**) &header );
107 if ( size == 0 || header == NULL ) {
108 Sys_Printf( "Unable to load %s.\n", source );
112 /* analyze ident/version */
113 memcpy( ident, header->ident, 4 );
115 version = LittleLong( header->version );
117 Sys_Printf( "Identity: %s\n", ident );
118 Sys_Printf( "Version: %d\n", version );
119 Sys_Printf( "---------------------------------------\n" );
121 /* analyze each lump */
122 for ( i = 0; i < 100; i++ )
124 /* call of duty swapped lump pairs */
126 offset = LittleLong( header->lumps[ i ].length );
127 length = LittleLong( header->lumps[ i ].offset );
130 /* standard lump pairs */
133 offset = LittleLong( header->lumps[ i ].offset );
134 length = LittleLong( header->lumps[ i ].length );
138 lump = (byte*) header + offset;
139 lumpInt = LittleLong( (int) *( (int*) lump ) );
140 lumpFloat = LittleFloat( (float) *( (float*) lump ) );
141 memcpy( lumpString, (char*) lump, ( (size_t)length < sizeof( lumpString ) ? (size_t)length : sizeof( lumpString ) - 1 ) );
142 lumpString[ sizeof( lumpString ) - 1 ] = '\0';
144 /* print basic lump info */
145 Sys_Printf( "Lump: %d\n", i );
146 Sys_Printf( "Offset: %d bytes\n", offset );
147 Sys_Printf( "Length: %d bytes\n", length );
149 /* only operate on valid lumps */
151 /* print data in 4 formats */
152 Sys_Printf( "As hex: %08X\n", lumpInt );
153 Sys_Printf( "As int: %d\n", lumpInt );
154 Sys_Printf( "As float: %f\n", lumpFloat );
155 Sys_Printf( "As string: %s\n", lumpString );
157 /* guess lump type */
158 if ( lumpString[ 0 ] == '{' && lumpString[ 2 ] == '"' ) {
159 Sys_Printf( "Type guess: IBSP LUMP_ENTITIES\n" );
161 else if ( strstr( lumpString, "textures/" ) ) {
162 Sys_Printf( "Type guess: IBSP LUMP_SHADERS\n" );
166 /* guess based on size/count */
167 for ( lumpTest = lumpTests; lumpTest->radix > 0; lumpTest++ )
169 if ( ( length % lumpTest->radix ) != 0 ) {
172 count = length / lumpTest->radix;
173 if ( count < lumpTest->minCount ) {
176 Sys_Printf( "Type guess: %s (%d x %d)\n", lumpTest->name, count, lumpTest->radix );
181 Sys_Printf( "---------------------------------------\n" );
184 if ( offset + length >= size ) {
190 Sys_Printf( "Lump count: %d\n", i + 1 );
191 Sys_Printf( "File size: %d bytes\n", size );
193 /* return to caller */