#include "bsploader.h" #include "dialogs/dialogs-gtk.h" #include "cmdlib.h" int numnodes; int numplanes; int numleafs; int numleafsurfaces; int numVisBytes; int numDrawVerts; int numDrawSurfaces; int numbrushes; int numbrushsides; int numleafbrushes; byte *visBytes = NULL; dnode_t *dnodes = NULL; dplane_t *dplanes = NULL; dleaf_t *dleafs = NULL; qdrawVert_t *drawVerts = NULL; dsurface_t *drawSurfaces = NULL; int *dleafsurfaces = NULL; dbrush_t *dbrushes = NULL; dbrushside_t *dbrushsides = NULL; int *dleafbrushes = NULL; #define BSP_IDENT (('P'<<24)+('S'<<16)+('B'<<8)+'I') #define Q3_BSP_VERSION 46 #define WOLF_BSP_VERSION 47 /* ================ FileLength ================ */ int FileLength (FILE *f) { int pos; int end; pos = ftell (f); fseek (f, 0, SEEK_END); end = ftell (f); fseek (f, pos, SEEK_SET); return end; } /* ============== LoadFile ============== */ bool LoadFile( const char *filename, byte **bufferptr) { FILE *f; int length; byte *buffer; f = fopen(filename, "rb"); if(!f) return false; length = FileLength (f); buffer = new byte[length+1]; buffer[length] = 0; fread(buffer, 1, length, f); fclose (f); *bufferptr = buffer; return true; } int LittleLong (int l) { #if defined(__BIG_ENDIAN__) std::reverse(reinterpret_cast(&l), reinterpret_cast(&l) + sizeof(int)); #endif return l; } float LittleFloat (float l) { #if defined(__BIG_ENDIAN__) std::reverse(reinterpret_cast(&l), reinterpret_cast(&l) + sizeof(float)); #endif return l; } /* ============= SwapBlock If all values are 32 bits, this can be used to swap everything ============= */ void SwapBlock( int *block, int sizeOfBlock ) { int i; sizeOfBlock >>= 2; for ( i = 0 ; i < sizeOfBlock ; i++ ) { block[i] = LittleLong( block[i] ); } } /* ============= SwapBSPFile Byte swaps all data in a bsp file. ============= */ void SwapBSPFile( void ) { int i; // models // SwapBlock( (int *)dmodels, nummodels * sizeof( dmodels[0] ) ); // shaders (don't swap the name) // for ( i = 0 ; i < numShaders ; i++ ) { // dshaders[i].contentFlags = LittleLong( dshaders[i].contentFlags ); // dshaders[i].surfaceFlags = LittleLong( dshaders[i].surfaceFlags ); // } // planes SwapBlock( (int *)dplanes, numplanes * sizeof( dplanes[0] ) ); // nodes SwapBlock( (int *)dnodes, numnodes * sizeof( dnodes[0] ) ); // leafs SwapBlock( (int *)dleafs, numleafs * sizeof( dleafs[0] ) ); // leaffaces SwapBlock( (int *)dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) ); // leafbrushes SwapBlock( (int *)dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) ); // brushes SwapBlock( (int *)dbrushes, numbrushes * sizeof( dbrushes[0] ) ); // brushsides SwapBlock( (int *)dbrushsides, numbrushsides * sizeof( dbrushsides[0] ) ); // vis ((int *)&visBytes)[0] = LittleLong( ((int *)&visBytes)[0] ); ((int *)&visBytes)[1] = LittleLong( ((int *)&visBytes)[1] ); // drawverts (don't swap colors ) for ( i = 0 ; i < numDrawVerts ; i++ ) { drawVerts[i].lightmap[0] = LittleFloat( drawVerts[i].lightmap[0] ); drawVerts[i].lightmap[1] = LittleFloat( drawVerts[i].lightmap[1] ); drawVerts[i].st[0] = LittleFloat( drawVerts[i].st[0] ); drawVerts[i].st[1] = LittleFloat( drawVerts[i].st[1] ); drawVerts[i].xyz[0] = LittleFloat( drawVerts[i].xyz[0] ); drawVerts[i].xyz[1] = LittleFloat( drawVerts[i].xyz[1] ); drawVerts[i].xyz[2] = LittleFloat( drawVerts[i].xyz[2] ); drawVerts[i].normal[0] = LittleFloat( drawVerts[i].normal[0] ); drawVerts[i].normal[1] = LittleFloat( drawVerts[i].normal[1] ); drawVerts[i].normal[2] = LittleFloat( drawVerts[i].normal[2] ); } // drawindexes // SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) ); // drawsurfs SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) ); // fogs // for ( i = 0 ; i < numFogs ; i++ ) { // dfogs[i].brushNum = LittleLong( dfogs[i].brushNum ); // dfogs[i].visibleSide = LittleLong( dfogs[i].visibleSide ); // } } /* ============= CopyLump ============= */ int CopyLump( dheader_t *header, int lump, void **dest, int size ) { int length, ofs; length = header->lumps[lump].filelen; ofs = header->lumps[lump].fileofs; if(length == 0) return 0; *dest = new byte[length]; memcpy( *dest, (byte *)header + ofs, length ); return length / size; } /* ============= LoadBSPFile ============= */ bool LoadBSPFile( const char *filename ) { dheader_t *header; // load the file header if(!LoadFile (filename, (byte **)&header)) return false; // swap the header SwapBlock( (int *)header, sizeof(*header) ); if ( header->ident != BSP_IDENT ) { DoMessageBox( "Cant find a valid IBSP file", "Error", eMB_OK); return false; } if ( (header->version != Q3_BSP_VERSION) && (header->version != WOLF_BSP_VERSION) ) { DoMessageBox( "File is incorrect version", "Error", eMB_OK); return false; } numbrushsides = CopyLump( header, LUMP_BRUSHES, (void**)&dbrushsides, sizeof(dbrushside_t) ); numbrushes = CopyLump( header, LUMP_BRUSHES, (void**)&dbrushes, sizeof(dbrush_t) ); numplanes = CopyLump( header, LUMP_PLANES, (void**)&dplanes, sizeof(dplane_t) ); numleafs = CopyLump( header, LUMP_LEAFS, (void**)&dleafs, sizeof(dleaf_t) ); numnodes = CopyLump( header, LUMP_NODES, (void**)&dnodes, sizeof(dnode_t) ); numDrawVerts = CopyLump( header, LUMP_DRAWVERTS, (void**)&drawVerts, sizeof(qdrawVert_t) ); numDrawSurfaces = CopyLump( header, LUMP_SURFACES, (void**)&drawSurfaces, sizeof(dsurface_t) ); numleafsurfaces = CopyLump( header, LUMP_LEAFSURFACES, (void**)&dleafsurfaces, sizeof(int) ); numVisBytes = CopyLump( header, LUMP_VISIBILITY, (void**)&visBytes, 1 ); numleafbrushes = CopyLump( header, LUMP_LEAFBRUSHES, (void**)&dleafbrushes, sizeof(int) ); delete header; // everything has been copied out // swap everything SwapBSPFile(); return true; } void FreeBSPData() { if(visBytes) delete visBytes; if(dnodes) delete dnodes; if(dplanes) delete dplanes; if(dleafs) delete dleafs; if(drawVerts) delete drawVerts; if(drawSurfaces) delete drawSurfaces; if(dleafsurfaces) delete dleafsurfaces; if(dleafbrushes) delete dleafbrushes; if(dbrushes) delete dbrushes; if(dbrushsides) delete dbrushsides; }