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