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