home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / qmapwos / src / readbsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-04  |  10.3 KB  |  500 lines

  1. /*  QMAP: Quake level viewer
  2.  *
  3.  *   readbsp.c
  4.  *
  5.  *  This file is a compilation of several
  6.  *  files released by John Carmack as part
  7.  *  of the Quake utilities source release.
  8.  *  No redistribution limitations appeared
  9.  *  in that distribution.
  10.  *
  11.  *  I don't claim any copyright either.
  12.  */
  13.  
  14. #include "bspfile.h"
  15. #include "mode.h"
  16.  
  17. // cmdlib.c
  18.  
  19. //#include <sys/types.h>
  20. //#include <sys/stat.h>
  21.  
  22. #define PATHSEPERATOR   '/'
  23.  
  24. // set these before calling CheckParm
  25. int myargc;
  26. char **myargv;
  27.  
  28. /*
  29. =================
  30. Error
  31.  
  32. For abnormal program terminations
  33. =================
  34. */
  35. void Error (char *error, ...)
  36. {
  37.    va_list argptr;
  38.  
  39. //   set_text();
  40.    printf ("************ ERROR ************\n");
  41.  
  42.    va_start (argptr,error);
  43.    vprintf (error,argptr);
  44.    va_end (argptr);
  45.    printf("\n");
  46.    exit (1);
  47. }
  48.  
  49. char *copystring(char *s)
  50. {
  51.    char   *b;
  52.    b = malloc(strlen(s)+1);
  53.    strcpy (b, s);
  54.    return b;
  55. }
  56.  
  57. /*
  58. ================
  59. filelength
  60. ================
  61. */
  62. int filelength (FILE *f)
  63. {
  64.    int      pos;
  65.    int      end;
  66.  
  67.    pos = ftell (f);
  68.    fseek (f, 0, SEEK_END);
  69.    end = ftell (f);
  70.    fseek (f, pos, SEEK_SET);
  71.  
  72.    return end;
  73. }
  74.  
  75.  
  76. FILE *SafeOpenWrite (char *filename)
  77. {
  78.    FILE   *f;
  79.  
  80.    f = fopen(filename, "wb");
  81.  
  82.    if (!f)
  83.       Error ("Error opening %s: %s",filename,strerror(errno));
  84.  
  85.    return f;
  86. }
  87.  
  88. FILE *SafeOpenRead (char *filename)
  89. {
  90.    FILE   *f;
  91.  
  92.    f = fopen(filename, "rb");
  93.  
  94.    if (!f)
  95.       Error ("Error opening %s: %s",filename,strerror(errno));
  96.  
  97.    return f;
  98. }
  99.  
  100.  
  101. void SafeRead (FILE *f, void *buffer, int count)
  102. {
  103.    if ( fread (buffer, 1, count, f) != (size_t)count)
  104.       Error ("File read failure");
  105. }
  106.  
  107.  
  108. void SafeWrite (FILE *f, void *buffer, int count)
  109. {
  110.    if (fwrite (buffer, 1, count, f) != (size_t)count)
  111.       Error ("File read failure");
  112. }
  113.  
  114.  
  115.  
  116. /*
  117. ==============
  118. LoadFile
  119. ==============
  120. */
  121. int    LoadFile (char *filename, void **bufferptr)
  122. {
  123.    FILE   *f;
  124.    int    length;
  125.    void    *buffer;
  126.  
  127.    f = SafeOpenRead (filename);
  128.    length = filelength (f);
  129.    buffer = malloc (length+1);
  130.    ((char *)buffer)[length] = 0;
  131.    SafeRead (f, buffer, length);
  132.    fclose (f);
  133.  
  134.    *bufferptr = buffer;
  135.    return length;
  136. }
  137.  
  138.  
  139. /*
  140. ==============
  141. SaveFile
  142. ==============
  143. */
  144. void    SaveFile (char *filename, void *buffer, int count)
  145. {
  146.    FILE   *f;
  147.  
  148.    f = SafeOpenWrite (filename);
  149.    SafeWrite (f, buffer, count);
  150.    fclose (f);
  151. }
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158. /*
  159. ============================================================================
  160.  
  161.                BYTE ORDER FUNCTIONS
  162.  
  163. ============================================================================
  164. */
  165.  
  166. short   LittleShort (short l)
  167. {
  168.    byte    b1,b2;
  169.  
  170.    b1 = l&255;
  171.    b2 = (l>>8)&255;
  172.  
  173.    return (b1<<8) + b2;
  174. }
  175.  
  176. short   BigShort (short l)
  177. {
  178.    return l;
  179. }
  180.  
  181.  
  182. int    LittleLong (int l)
  183. {
  184.    byte    b1,b2,b3,b4;
  185.  
  186.    b1 = l&255;
  187.    b2 = (l>>8)&255;
  188.    b3 = (l>>16)&255;
  189.    b4 = (l>>24)&255;
  190.  
  191.    return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
  192. }
  193.  
  194. int    BigLong (int l)
  195. {
  196.    return l;
  197. }
  198.  
  199.  
  200. float   LittleFloat (float l)
  201. {
  202.    union {byte b[4]; float f;} in, out;
  203.    
  204.    in.f = l;
  205.    out.b[0] = in.b[3];
  206.    out.b[1] = in.b[2];
  207.    out.b[2] = in.b[1];
  208.    out.b[3] = in.b[0];
  209.    
  210.    return out.f;
  211. }
  212.  
  213. float   BigFloat (float l)
  214. {
  215.    return l;
  216. }
  217.  
  218. //=============================================================================
  219.  
  220. int       nummodels;
  221. dmodel_t    dmodels[MAX_MAP_MODELS];
  222.  
  223. int          visdatasize;
  224. byte        dvisdata[MAX_MAP_VISIBILITY];
  225.  
  226. int          lightdatasize;
  227. byte        dlightdata[MAX_MAP_LIGHTING];
  228.  
  229. int          texdatasize;
  230. byte        dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
  231.  
  232. int          entdatasize;
  233. char        dentdata[MAX_MAP_ENTSTRING];
  234.  
  235. int        numleafs;
  236. dleaf_t      dleafs[MAX_MAP_LEAFS];
  237.  
  238. int        numplanes;
  239. dplane_t     dplanes[MAX_MAP_PLANES];
  240.  
  241. int        numvertexes;
  242. dvertex_t    dvertexes[MAX_MAP_VERTS];
  243.  
  244. int        numnodes;
  245. dnode_t      dnodes[MAX_MAP_NODES];
  246.  
  247. int       numtexinfo;
  248. texinfo_t    texinfo[MAX_MAP_TEXINFO];
  249.  
  250. int        numfaces;
  251. dface_t      dfaces[MAX_MAP_FACES];
  252.  
  253. int        numclipnodes;
  254. dclipnode_t  dclipnodes[MAX_MAP_CLIPNODES];
  255.  
  256. int        numedges;
  257. dedge_t      dedges[MAX_MAP_EDGES];
  258.  
  259. int               nummarksurfaces;
  260. unsigned short      dmarksurfaces[MAX_MAP_MARKSURFACES];
  261.  
  262. int       numsurfedges;
  263. int         dsurfedges[MAX_MAP_SURFEDGES];
  264.  
  265. //=============================================================================
  266.  
  267. /*
  268. =============
  269. SwapBSPFile
  270.  
  271. Byte swaps all data in a bsp file.
  272. =============
  273. */
  274. void SwapBSPFile (qboolean todisk)
  275. {
  276.    int            i, j, c;
  277.    dmodel_t      *d;
  278.    dmiptexlump_t   *mtl;
  279.  
  280.    
  281. // models   
  282.    for (i=0 ; i<nummodels ; i++)
  283.    {
  284.       d = &dmodels[i];
  285.  
  286.       for (j=0 ; j<MAX_MAP_HULLS ; j++)
  287.          d->headnode[j] = LittleLong (d->headnode[j]);
  288.  
  289.       d->visleafs = LittleLong (d->visleafs);
  290.       d->firstface = LittleLong (d->firstface);
  291.       d->numfaces = LittleLong (d->numfaces);
  292.       
  293.       for (j=0 ; j<3 ; j++)
  294.       {
  295.          d->mins[j] = LittleFloat(d->mins[j]);
  296.          d->maxs[j] = LittleFloat(d->maxs[j]);
  297.          d->origin[j] = LittleFloat(d->origin[j]);
  298.       }
  299.    }
  300.  
  301. //
  302. // vertexes
  303. //
  304.    for (i=0 ; i<numvertexes ; i++)
  305.    {
  306.       for (j=0 ; j<3 ; j++)
  307.          dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
  308.    }
  309.       
  310. //
  311. // planes
  312. //   
  313.    for (i=0 ; i<numplanes ; i++)
  314.    {
  315.       for (j=0 ; j<3 ; j++)
  316.          dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
  317.       dplanes[i].dist = LittleFloat (dplanes[i].dist);
  318.       dplanes[i].type = LittleLong (dplanes[i].type);
  319.    }
  320.    
  321. //
  322. // texinfos
  323. //   
  324.    for (i=0 ; i<numtexinfo ; i++)
  325.    {
  326.       for (j=0 ; j<8 ; j++)
  327.          texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
  328.       texinfo[i].miptex = LittleLong (texinfo[i].miptex);
  329.       texinfo[i].flags = LittleLong (texinfo[i].flags);
  330.    }
  331.    
  332. //
  333. // faces
  334. //
  335.    for (i=0 ; i<numfaces ; i++)
  336.    {
  337.       dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
  338.       dfaces[i].planenum = LittleShort (dfaces[i].planenum);
  339.       dfaces[i].side = LittleShort (dfaces[i].side);
  340.       dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
  341.       dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
  342.       dfaces[i].numedges = LittleShort (dfaces[i].numedges);
  343.    }
  344.  
  345. //
  346. // nodes
  347. //
  348.    for (i=0 ; i<numnodes ; i++)
  349.    {
  350.       dnodes[i].planenum = LittleLong (dnodes[i].planenum);
  351.       for (j=0 ; j<3 ; j++)
  352.       {
  353.          dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
  354.          dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
  355.       }
  356.       dnodes[i].children[0] = LittleShort (dnodes[i].children[0]);
  357.       dnodes[i].children[1] = LittleShort (dnodes[i].children[1]);
  358.       dnodes[i].firstface = LittleShort (dnodes[i].firstface);
  359.       dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
  360.    }
  361.  
  362. //
  363. // leafs
  364. //
  365.    for (i=0 ; i<numleafs ; i++)
  366.    {
  367.       dleafs[i].contents = LittleLong (dleafs[i].contents);
  368.       for (j=0 ; j<3 ; j++)
  369.       {
  370.          dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
  371.          dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
  372.       }
  373.  
  374.       dleafs[i].firstmarksurface = LittleShort (dleafs[i].firstmarksurface);
  375.       dleafs[i].nummarksurfaces = LittleShort (dleafs[i].nummarksurfaces);
  376.       dleafs[i].visofs = LittleLong (dleafs[i].visofs);
  377.    }
  378.  
  379. //
  380. // clipnodes
  381. //
  382.    for (i=0 ; i<numclipnodes ; i++)
  383.    {
  384.       dclipnodes[i].planenum = LittleLong (dclipnodes[i].planenum);
  385.       dclipnodes[i].children[0] = LittleShort (dclipnodes[i].children[0]);
  386.       dclipnodes[i].children[1] = LittleShort (dclipnodes[i].children[1]);
  387.    }
  388.  
  389. //
  390. // miptex
  391. //
  392.    if (texdatasize)
  393.    {
  394.       mtl = (dmiptexlump_t *)dtexdata;
  395.       if (todisk)
  396.          c = mtl->nummiptex;
  397.       else
  398.          c = LittleLong(mtl->nummiptex);
  399.       mtl->nummiptex = LittleLong (mtl->nummiptex);
  400.       for (i=0 ; i<c ; i++)
  401.       {
  402.         miptex_t *t;
  403.          t=(miptex_t *)((char *)mtl+(mtl->dataofs[i] = LittleLong(mtl->dataofs[i])));
  404.          t->width=LittleLong(t->width);
  405.          t->height=LittleLong(t->height);
  406.          t->offsets[0]=LittleLong(t->offsets[0]);
  407.          t->offsets[1]=LittleLong(t->offsets[1]);
  408.          t->offsets[2]=LittleLong(t->offsets[2]);
  409.          t->offsets[3]=LittleLong(t->offsets[3]);
  410.       }
  411.    }
  412.    
  413. //
  414. // marksurfaces
  415. //
  416.    for (i=0 ; i<nummarksurfaces ; i++)
  417.       dmarksurfaces[i] = LittleShort (dmarksurfaces[i]);
  418.  
  419. //
  420. // surfedges
  421. //
  422.    for (i=0 ; i<numsurfedges ; i++)
  423.       dsurfedges[i] = LittleLong (dsurfedges[i]);
  424.  
  425. //
  426. // edges
  427. //
  428.    for (i=0 ; i<numedges ; i++)
  429.    {
  430.       dedges[i].v[0] = LittleShort (dedges[i].v[0]);
  431.       dedges[i].v[1] = LittleShort (dedges[i].v[1]);
  432.    }
  433. }
  434.  
  435.  
  436. dheader_t   *header;
  437.  
  438. int CopyLump (int lump, void *dest, int size)
  439. {
  440.    int      length, ofs;
  441.  
  442.    length = header->lumps[lump].filelen;
  443.    ofs = header->lumps[lump].fileofs;
  444.    
  445.    if (length % size)
  446.       Error ("LoadBSPFile: odd lump size");
  447.    
  448.    memcpy (dest, (byte *)header + ofs, length);
  449.  
  450.    return length / size;
  451. }
  452.  
  453. /*
  454. =============
  455. LoadBSPFile
  456. =============
  457. */
  458. void   LoadBSPFile (char *filename)
  459. {
  460.    int         i;
  461.    
  462. //
  463. // load the file header
  464. //
  465.    LoadFile (filename, (void **)&header);
  466.  
  467. // swap the header
  468.    for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
  469.       ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
  470.  
  471.    if (header->version != BSPVERSION) {
  472.       printf("******* WARNING ********\n");
  473.       printf("%s is version %i, not %i", filename, i, BSPVERSION);
  474.    }
  475.  
  476.    nummodels = CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t));
  477.    numvertexes = CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t));
  478.    numplanes = CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t));
  479.    numleafs = CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t));
  480.    numnodes = CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t));
  481.    numtexinfo = CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t));
  482.    numclipnodes = CopyLump (LUMP_CLIPNODES, dclipnodes, sizeof(dclipnode_t));
  483.    numfaces = CopyLump (LUMP_FACES, dfaces, sizeof(dface_t));
  484.    nummarksurfaces = CopyLump (LUMP_MARKSURFACES, dmarksurfaces, sizeof(dmarksurfaces[0]));
  485.    numsurfedges = CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0]));
  486.    numedges = CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t));
  487.  
  488.    texdatasize = CopyLump (LUMP_TEXTURES, dtexdata, 1);
  489.    visdatasize = CopyLump (LUMP_VISIBILITY, dvisdata, 1);
  490.    lightdatasize = CopyLump (LUMP_LIGHTING, dlightdata, 1);
  491.    entdatasize = CopyLump (LUMP_ENTITIES, dentdata, 1);
  492.  
  493.    free (header);      // everything has been copied out
  494.       
  495. //
  496. // swap everything
  497. //   
  498.    SwapBSPFile (false);
  499. }
  500.