1 #include "bsploader.h"
2 #include "dialogs/dialogs-gtk.h"
3 #include "cmdlib.h"
4 
5 int numnodes;
6 int numplanes;
7 int numleafs;
8 int numleafsurfaces;
9 int numVisBytes;
10 int numDrawVerts;
11 int numDrawSurfaces;
12 int numbrushes;
13 int numbrushsides;
14 int numleafbrushes;
15 
16 byte                *visBytes =           NULL;
17 dnode_t           *dnodes =             NULL;
18 dplane_t          *dplanes =              NULL;
19 dleaf_t           *dleafs =             NULL;
20 qdrawVert_t   *drawVerts =        NULL;
21 dsurface_t    *drawSurfaces =       NULL;
22 int                 *dleafsurfaces =    NULL;
23 dbrush_t          *dbrushes =             NULL;
24 dbrushside_t    *dbrushsides =      NULL;
25 int                 *dleafbrushes =     NULL;
26 
27 #define BSP_IDENT   ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' )
28 #define Q3_BSP_VERSION          46
29 #define WOLF_BSP_VERSION            47
30 
31 /*
32    ================
33    FileLength
34    ================
35  */
FileLength(FILE * f)36 int FileLength( FILE *f ){
37 	int pos;
38 	int end;
39 
40 	pos = ftell( f );
41 	fseek( f, 0, SEEK_END );
42 	end = ftell( f );
43 	fseek( f, pos, SEEK_SET );
44 
45 	return end;
46 }
47 
48 /*
49    ==============
50    LoadFile
51    ==============
52  */
LoadFile(const char * filename,byte ** bufferptr)53 bool    LoadFile( const char *filename, byte **bufferptr ){
54 	FILE    *f;
55 	int length;
56 	byte    *buffer;
57 
58 	f = fopen( filename, "rb" );
59 	if ( !f ) {
60 		return false;
61 	}
62 
63 	length = FileLength( f );
64 	buffer = new byte[length + 1];
65 	buffer[length] = 0;
66 	fread( buffer, 1, length, f );
67 	fclose( f );
68 
69 	*bufferptr = buffer;
70 	return true;
71 }
72 
LittleLong(int l)73 int    LittleLong( int l ){
74 #if defined( __BIG_ENDIAN__ )
75 	std::reverse( reinterpret_cast<unsigned char*>( &l ), reinterpret_cast<unsigned char*>( &l ) + sizeof( int ) );
76 #endif
77 	return l;
78 }
79 
LittleFloat(float l)80 float   LittleFloat( float l ){
81 #if defined( __BIG_ENDIAN__ )
82 	std::reverse( reinterpret_cast<unsigned char*>( &l ), reinterpret_cast<unsigned char*>( &l ) + sizeof( float ) );
83 #endif
84 	return l;
85 }
86 
87 /*
88    =============
89    SwapBlock
90 
91    If all values are 32 bits, this can be used to swap everything
92    =============
93  */
SwapBlock(int * block,int sizeOfBlock)94 void SwapBlock( int *block, int sizeOfBlock ) {
95 	int i;
96 
97 	sizeOfBlock >>= 2;
98 	for ( i = 0 ; i < sizeOfBlock ; i++ ) {
99 		block[i] = LittleLong( block[i] );
100 	}
101 }
102 
103 /*
104    =============
105    SwapBSPFile
106 
107    Byte swaps all data in a bsp file.
108    =============
109  */
SwapBSPFile(void)110 void SwapBSPFile( void ) {
111 	int i;
112 
113 	// models
114 //	SwapBlock( (int *)dmodels, nummodels * sizeof( dmodels[0] ) );
115 
116 	// shaders (don't swap the name)
117 //	for ( i = 0 ; i < numShaders ; i++ ) {
118 //		dshaders[i].contentFlags = LittleLong( dshaders[i].contentFlags );
119 //		dshaders[i].surfaceFlags = LittleLong( dshaders[i].surfaceFlags );
120 //	}
121 
122 	// planes
123 	SwapBlock( (int *)dplanes, numplanes * sizeof( dplanes[0] ) );
124 
125 	// nodes
126 	SwapBlock( (int *)dnodes, numnodes * sizeof( dnodes[0] ) );
127 
128 	// leafs
129 	SwapBlock( (int *)dleafs, numleafs * sizeof( dleafs[0] ) );
130 
131 	// leaffaces
132 	SwapBlock( (int *)dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) );
133 
134 	// leafbrushes
135 	SwapBlock( (int *)dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) );
136 
137 	// brushes
138 	SwapBlock( (int *)dbrushes, numbrushes * sizeof( dbrushes[0] ) );
139 
140 	// brushsides
141 	SwapBlock( (int *)dbrushsides, numbrushsides * sizeof( dbrushsides[0] ) );
142 
143 	// vis
144 	( (int *)&visBytes )[0] = LittleLong( ( (int *)&visBytes )[0] );
145 	( (int *)&visBytes )[1] = LittleLong( ( (int *)&visBytes )[1] );
146 
147 	// drawverts (don't swap colors )
148 	for ( i = 0 ; i < numDrawVerts ; i++ ) {
149 		drawVerts[i].lightmap[0] = LittleFloat( drawVerts[i].lightmap[0] );
150 		drawVerts[i].lightmap[1] = LittleFloat( drawVerts[i].lightmap[1] );
151 		drawVerts[i].st[0] = LittleFloat( drawVerts[i].st[0] );
152 		drawVerts[i].st[1] = LittleFloat( drawVerts[i].st[1] );
153 		drawVerts[i].xyz[0] = LittleFloat( drawVerts[i].xyz[0] );
154 		drawVerts[i].xyz[1] = LittleFloat( drawVerts[i].xyz[1] );
155 		drawVerts[i].xyz[2] = LittleFloat( drawVerts[i].xyz[2] );
156 		drawVerts[i].normal[0] = LittleFloat( drawVerts[i].normal[0] );
157 		drawVerts[i].normal[1] = LittleFloat( drawVerts[i].normal[1] );
158 		drawVerts[i].normal[2] = LittleFloat( drawVerts[i].normal[2] );
159 	}
160 
161 	// drawindexes
162 //	SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) );
163 
164 	// drawsurfs
165 	SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) );
166 
167 	// fogs
168 //	for ( i = 0 ; i < numFogs ; i++ ) {
169 //		dfogs[i].brushNum = LittleLong( dfogs[i].brushNum );
170 //		dfogs[i].visibleSide = LittleLong( dfogs[i].visibleSide );
171 //	}
172 }
173 
174 /*
175    =============
176    CopyLump
177    =============
178  */
CopyLump(dheader_t * header,int lump,void ** dest,int size)179 int CopyLump( dheader_t *header, int lump, void **dest, int size ) {
180 	int length, ofs;
181 
182 	length = header->lumps[lump].filelen;
183 	ofs = header->lumps[lump].fileofs;
184 
185 	if ( length == 0 ) {
186 		return 0;
187 	}
188 
189 	*dest = new byte[length];
190 	memcpy( *dest, (byte *)header + ofs, length );
191 
192 	return length / size;
193 }
194 
195 /*
196    =============
197    LoadBSPFile
198    =============
199  */
LoadBSPFile(const char * filename)200 bool    LoadBSPFile( const char *filename ) {
201 	dheader_t   *header;
202 
203 	// load the file header
204 	if ( !LoadFile( filename, (byte **)&header ) ) {
205 		return false;
206 	}
207 
208 	// swap the header
209 	SwapBlock( (int *)header, sizeof( *header ) );
210 
211 	if ( header->ident != BSP_IDENT ) {
212 		DoMessageBox( "Cant find a valid IBSP file", "Error", eMB_OK );
213 		return false;
214 	}
215 	if ( ( header->version != Q3_BSP_VERSION ) &&
216 		 ( header->version != WOLF_BSP_VERSION ) ) {
217 		DoMessageBox( "File is incorrect version", "Error", eMB_OK );
218 		return false;
219 	}
220 
221 	numbrushsides =     CopyLump( header, LUMP_BRUSHES,         (void**)&dbrushsides,   sizeof( dbrushside_t ) );
222 	numbrushes =        CopyLump( header, LUMP_BRUSHES,         (void**)&dbrushes,      sizeof( dbrush_t ) );
223 	numplanes =         CopyLump( header, LUMP_PLANES,          (void**)&dplanes,       sizeof( dplane_t ) );
224 	numleafs =          CopyLump( header, LUMP_LEAFS,           (void**)&dleafs,        sizeof( dleaf_t ) );
225 	numnodes =          CopyLump( header, LUMP_NODES,           (void**)&dnodes,        sizeof( dnode_t ) );
226 	numDrawVerts =      CopyLump( header, LUMP_DRAWVERTS,       (void**)&drawVerts,     sizeof( qdrawVert_t ) );
227 	numDrawSurfaces =   CopyLump( header, LUMP_SURFACES,        (void**)&drawSurfaces,  sizeof( dsurface_t ) );
228 	numleafsurfaces =   CopyLump( header, LUMP_LEAFSURFACES,    (void**)&dleafsurfaces, sizeof( int ) );
229 	numVisBytes =       CopyLump( header, LUMP_VISIBILITY,      (void**)&visBytes,      1 );
230 	numleafbrushes =    CopyLump( header, LUMP_LEAFBRUSHES,     (void**)&dleafbrushes,  sizeof( int ) );
231 
232 	delete header;      // everything has been copied out
233 
234 	// swap everything
235 	SwapBSPFile();
236 
237 	return true;
238 }
239 
FreeBSPData()240 void FreeBSPData(){
241 	if ( visBytes ) {
242 		delete visBytes;
243 	}
244 	if ( dnodes ) {
245 		delete dnodes;
246 	}
247 	if ( dplanes ) {
248 		delete dplanes;
249 	}
250 	if ( dleafs ) {
251 		delete dleafs;
252 	}
253 	if ( drawVerts ) {
254 		delete drawVerts;
255 	}
256 	if ( drawSurfaces ) {
257 		delete drawSurfaces;
258 	}
259 	if ( dleafsurfaces ) {
260 		delete dleafsurfaces;
261 	}
262 	if ( dleafbrushes ) {
263 		delete dleafbrushes;
264 	}
265 	if ( dbrushes ) {
266 		delete dbrushes;
267 	}
268 	if ( dbrushsides ) {
269 		delete dbrushsides;
270 	}
271 }
272