3411 lines
129 KiB
C++
3411 lines
129 KiB
C++
/* Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
See file, 'COPYING', for details.
|
|
*/
|
|
|
|
#include <common/cmdlib.hh>
|
|
#include <common/mathlib.hh>
|
|
#include <common/bspfile.hh>
|
|
|
|
const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP" };
|
|
const bspversion_t bspver_q1 { BSPVERSION, NO_VERSION, "bsp29", "Quake BSP" };
|
|
/* Hexen II doesn't use a separate version, but we can still use a separate tag/name for it */
|
|
const bspversion_t bspver_h2 { BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP" };
|
|
const bspversion_t bspver_bsp2 { BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2" };
|
|
const bspversion_t bspver_bsp2rmq { BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ" };
|
|
const bspversion_t bspver_hl { BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP" };
|
|
const bspversion_t bspver_q2 { Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP" };
|
|
const bspversion_t bspver_qbism { Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP" };
|
|
|
|
static const char *
|
|
BSPVersionString(const bspversion_t *version)
|
|
{
|
|
if (version->name) {
|
|
return version->name;
|
|
}
|
|
|
|
static char buffers[2][20];
|
|
static int index;
|
|
char *buffer = buffers[1 & ++index];
|
|
if (version->version != NO_VERSION) {
|
|
q_snprintf(buffer, sizeof(buffers[0]), "%d:%d", version->version, version->ident);
|
|
} else {
|
|
q_snprintf(buffer, sizeof(buffers[0]), "%d", version->version);
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
static qboolean
|
|
BSPVersionSupported(int32_t ident, int32_t version, const bspversion_t **out_version)
|
|
{
|
|
for (const bspversion_t *bspver : bspversions) {
|
|
if (bspver->ident == ident && bspver->version == version) {
|
|
*out_version = bspver;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP BYTE SWAPPING
|
|
* =========================================================================
|
|
*/
|
|
|
|
typedef enum { TO_DISK, TO_CPU } swaptype_t;
|
|
|
|
static void
|
|
SwapBSPVertexes(int numvertexes, dvertex_t *verticies)
|
|
{
|
|
dvertex_t *vertex = verticies;
|
|
int i, j;
|
|
|
|
for (i = 0; i < numvertexes; i++, vertex++)
|
|
for (j = 0; j < 3; j++)
|
|
vertex->point[j] = LittleFloat(vertex->point[j]);
|
|
}
|
|
|
|
static void
|
|
SwapBSPPlanes(int numplanes, dplane_t *planes)
|
|
{
|
|
dplane_t *plane = planes;
|
|
int i, j;
|
|
|
|
for (i = 0; i < numplanes; i++, plane++) {
|
|
for (j = 0; j < 3; j++)
|
|
plane->normal[j] = LittleFloat(plane->normal[j]);
|
|
plane->dist = LittleFloat(plane->dist);
|
|
plane->type = LittleLong(plane->type);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSPTexinfo(int numtexinfo, texinfo_t *texinfos)
|
|
{
|
|
texinfo_t *texinfo = texinfos;
|
|
int i, j;
|
|
|
|
for (i = 0; i < numtexinfo; i++, texinfo++) {
|
|
for (j = 0; j < 4; j++) {
|
|
texinfo->vecs[0][j] = LittleFloat(texinfo->vecs[0][j]);
|
|
texinfo->vecs[1][j] = LittleFloat(texinfo->vecs[1][j]);
|
|
}
|
|
texinfo->miptex = LittleLong(texinfo->miptex);
|
|
texinfo->flags = LittleLong(texinfo->flags);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP29Faces(int numfaces, bsp29_dface_t *faces)
|
|
{
|
|
bsp29_dface_t *face = faces;
|
|
int i;
|
|
|
|
for (i = 0; i < numfaces; i++, face++) {
|
|
face->texinfo = LittleShort(face->texinfo);
|
|
face->planenum = LittleShort(face->planenum);
|
|
face->side = LittleShort(face->side);
|
|
face->lightofs = LittleLong(face->lightofs);
|
|
face->firstedge = LittleLong(face->firstedge);
|
|
face->numedges = LittleShort(face->numedges);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2Faces(int numfaces, bsp2_dface_t *faces)
|
|
{
|
|
bsp2_dface_t *face = faces;
|
|
int i;
|
|
|
|
for (i = 0; i < numfaces; i++, face++) {
|
|
face->texinfo = LittleLong(face->texinfo);
|
|
face->planenum = LittleLong(face->planenum);
|
|
face->side = LittleLong(face->side);
|
|
face->lightofs = LittleLong(face->lightofs);
|
|
face->firstedge = LittleLong(face->firstedge);
|
|
face->numedges = LittleLong(face->numedges);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP29Nodes(int numnodes, bsp29_dnode_t *nodes)
|
|
{
|
|
bsp29_dnode_t *node = nodes;
|
|
int i, j;
|
|
|
|
/* nodes */
|
|
for (i = 0; i < numnodes; i++, node++) {
|
|
node->planenum = LittleLong(node->planenum);
|
|
for (j = 0; j < 3; j++) {
|
|
node->mins[j] = LittleShort(node->mins[j]);
|
|
node->maxs[j] = LittleShort(node->maxs[j]);
|
|
}
|
|
node->children[0] = LittleShort(node->children[0]);
|
|
node->children[1] = LittleShort(node->children[1]);
|
|
node->firstface = LittleShort(node->firstface);
|
|
node->numfaces = LittleShort(node->numfaces);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2rmqNodes(int numnodes, bsp2rmq_dnode_t *nodes)
|
|
{
|
|
bsp2rmq_dnode_t *node = nodes;
|
|
int i, j;
|
|
|
|
/* nodes */
|
|
for (i = 0; i < numnodes; i++, node++) {
|
|
node->planenum = LittleLong(node->planenum);
|
|
for (j = 0; j < 3; j++) {
|
|
node->mins[j] = LittleShort(node->mins[j]);
|
|
node->maxs[j] = LittleShort(node->maxs[j]);
|
|
}
|
|
node->children[0] = LittleLong(node->children[0]);
|
|
node->children[1] = LittleLong(node->children[1]);
|
|
node->firstface = LittleLong(node->firstface);
|
|
node->numfaces = LittleLong(node->numfaces);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2Nodes(int numnodes, bsp2_dnode_t *nodes)
|
|
{
|
|
bsp2_dnode_t *node = nodes;
|
|
int i, j;
|
|
|
|
/* nodes */
|
|
for (i = 0; i < numnodes; i++, node++) {
|
|
node->planenum = LittleLong(node->planenum);
|
|
for (j = 0; j < 3; j++) {
|
|
node->mins[j] = LittleFloat(node->mins[j]);
|
|
node->maxs[j] = LittleFloat(node->maxs[j]);
|
|
}
|
|
node->children[0] = LittleLong(node->children[0]);
|
|
node->children[1] = LittleLong(node->children[1]);
|
|
node->firstface = LittleLong(node->firstface);
|
|
node->numfaces = LittleLong(node->numfaces);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP29Leafs(int numleafs, bsp29_dleaf_t *leafs)
|
|
{
|
|
bsp29_dleaf_t *leaf = leafs;
|
|
int i, j;
|
|
|
|
for (i = 0; i < numleafs; i++, leaf++) {
|
|
leaf->contents = LittleLong(leaf->contents);
|
|
for (j = 0; j < 3; j++) {
|
|
leaf->mins[j] = LittleShort(leaf->mins[j]);
|
|
leaf->maxs[j] = LittleShort(leaf->maxs[j]);
|
|
}
|
|
leaf->firstmarksurface = LittleShort(leaf->firstmarksurface);
|
|
leaf->nummarksurfaces = LittleShort(leaf->nummarksurfaces);
|
|
leaf->visofs = LittleLong(leaf->visofs);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2rmqLeafs(int numleafs, bsp2rmq_dleaf_t *leafs)
|
|
{
|
|
bsp2rmq_dleaf_t *leaf = leafs;
|
|
int i, j;
|
|
|
|
for (i = 0; i < numleafs; i++, leaf++) {
|
|
leaf->contents = LittleLong(leaf->contents);
|
|
for (j = 0; j < 3; j++) {
|
|
leaf->mins[j] = LittleShort(leaf->mins[j]);
|
|
leaf->maxs[j] = LittleShort(leaf->maxs[j]);
|
|
}
|
|
leaf->firstmarksurface = LittleLong(leaf->firstmarksurface);
|
|
leaf->nummarksurfaces = LittleLong(leaf->nummarksurfaces);
|
|
leaf->visofs = LittleLong(leaf->visofs);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2Leafs(int numleafs, bsp2_dleaf_t *leafs)
|
|
{
|
|
bsp2_dleaf_t *leaf = leafs;
|
|
int i, j;
|
|
|
|
for (i = 0; i < numleafs; i++, leaf++) {
|
|
leaf->contents = LittleLong(leaf->contents);
|
|
for (j = 0; j < 3; j++) {
|
|
leaf->mins[j] = LittleFloat(leaf->mins[j]);
|
|
leaf->maxs[j] = LittleFloat(leaf->maxs[j]);
|
|
}
|
|
leaf->firstmarksurface = LittleLong(leaf->firstmarksurface);
|
|
leaf->nummarksurfaces = LittleLong(leaf->nummarksurfaces);
|
|
leaf->visofs = LittleLong(leaf->visofs);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP29Clipnodes(int numclipnodes, bsp29_dclipnode_t *clipnodes)
|
|
{
|
|
bsp29_dclipnode_t *clipnode = clipnodes;
|
|
int i;
|
|
|
|
for (i = 0; i < numclipnodes; i++, clipnode++) {
|
|
clipnode->planenum = LittleLong(clipnode->planenum);
|
|
clipnode->children[0] = LittleShort(clipnode->children[0]);
|
|
clipnode->children[1] = LittleShort(clipnode->children[1]);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2Clipnodes(int numclipnodes, bsp2_dclipnode_t *clipnodes)
|
|
{
|
|
bsp2_dclipnode_t *clipnode = clipnodes;
|
|
int i;
|
|
|
|
for (i = 0; i < numclipnodes; i++, clipnode++) {
|
|
clipnode->planenum = LittleLong(clipnode->planenum);
|
|
clipnode->children[0] = LittleLong(clipnode->children[0]);
|
|
clipnode->children[1] = LittleLong(clipnode->children[1]);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP29Marksurfaces(int nummarksurfaces, uint16_t *dmarksurfaces)
|
|
{
|
|
uint16_t *marksurface = dmarksurfaces;
|
|
int i;
|
|
|
|
for (i = 0; i < nummarksurfaces; i++, marksurface++)
|
|
*marksurface = LittleShort(*marksurface);
|
|
}
|
|
|
|
static void
|
|
SwapBSP2Marksurfaces(int nummarksurfaces, uint32_t *dmarksurfaces)
|
|
{
|
|
uint32_t *marksurface = dmarksurfaces;
|
|
int i;
|
|
|
|
for (i = 0; i < nummarksurfaces; i++, marksurface++)
|
|
*marksurface = LittleLong(*marksurface);
|
|
}
|
|
|
|
static void
|
|
SwapBSPSurfedges(int numsurfedges, int32_t *dsurfedges)
|
|
{
|
|
int32_t *surfedge = dsurfedges;
|
|
int i;
|
|
|
|
for (i = 0; i < numsurfedges; i++, surfedge++)
|
|
*surfedge = LittleLong(*surfedge);
|
|
}
|
|
|
|
static void
|
|
SwapBSP29Edges(int numedges, bsp29_dedge_t *dedges)
|
|
{
|
|
bsp29_dedge_t *edge = dedges;
|
|
int i;
|
|
|
|
for (i = 0; i < numedges; i++, edge++) {
|
|
edge->v[0] = LittleShort(edge->v[0]);
|
|
edge->v[1] = LittleShort(edge->v[1]);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSP2Edges(int numedges, bsp2_dedge_t *dedges)
|
|
{
|
|
bsp2_dedge_t *edge = dedges;
|
|
int i;
|
|
|
|
for (i = 0; i < numedges; i++, edge++) {
|
|
edge->v[0] = LittleLong(edge->v[0]);
|
|
edge->v[1] = LittleLong(edge->v[1]);
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSPModels(int nummodels, dmodel_t *dmodels)
|
|
{
|
|
dmodel_t *dmodel = dmodels;
|
|
int i, j;
|
|
|
|
for (i = 0; i < nummodels; i++, dmodel++) {
|
|
for (j = 0; j < MAX_MAP_HULLS; j++)
|
|
dmodel->headnode[j] = LittleLong(dmodel->headnode[j]);
|
|
dmodel->visleafs = LittleLong(dmodel->visleafs);
|
|
dmodel->firstface = LittleLong(dmodel->firstface);
|
|
dmodel->numfaces = LittleLong(dmodel->numfaces);
|
|
for (j = 0; j < 3; j++) {
|
|
dmodel->mins[j] = LittleFloat(dmodel->mins[j]);
|
|
dmodel->maxs[j] = LittleFloat(dmodel->maxs[j]);
|
|
dmodel->origin[j] = LittleFloat(dmodel->origin[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
SwapBSPMiptex(int texdatasize, dmiptexlump_t *header, const swaptype_t swap)
|
|
{
|
|
int i, count;
|
|
|
|
if (!texdatasize)
|
|
return;
|
|
|
|
count = header->nummiptex;
|
|
if (swap == TO_CPU)
|
|
count = LittleLong(count);
|
|
|
|
header->nummiptex = LittleLong(header->nummiptex);
|
|
for (i = 0; i < count; i++)
|
|
header->dataofs[i] = LittleLong(header->dataofs[i]);
|
|
}
|
|
|
|
/*
|
|
=============
|
|
Q2_SwapBSPFile
|
|
|
|
Byte swaps all data in a bsp file.
|
|
=============
|
|
*/
|
|
void Q2_SwapBSPFile (q2bsp_t *bsp, qboolean todisk)
|
|
{
|
|
int i, j;
|
|
q2_dmodel_t *d;
|
|
|
|
|
|
// models
|
|
for (i=0 ; i<bsp->nummodels ; i++)
|
|
{
|
|
d = &bsp->dmodels[i];
|
|
|
|
d->firstface = LittleLong (d->firstface);
|
|
d->numfaces = LittleLong (d->numfaces);
|
|
d->headnode = LittleLong (d->headnode);
|
|
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
d->mins[j] = LittleFloat(d->mins[j]);
|
|
d->maxs[j] = LittleFloat(d->maxs[j]);
|
|
d->origin[j] = LittleFloat(d->origin[j]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// vertexes
|
|
//
|
|
for (i=0 ; i<bsp->numvertexes ; i++)
|
|
{
|
|
for (j=0 ; j<3 ; j++)
|
|
bsp->dvertexes[i].point[j] = LittleFloat (bsp->dvertexes[i].point[j]);
|
|
}
|
|
|
|
//
|
|
// planes
|
|
//
|
|
for (i=0 ; i<bsp->numplanes ; i++)
|
|
{
|
|
for (j=0 ; j<3 ; j++)
|
|
bsp->dplanes[i].normal[j] = LittleFloat (bsp->dplanes[i].normal[j]);
|
|
bsp->dplanes[i].dist = LittleFloat (bsp->dplanes[i].dist);
|
|
bsp->dplanes[i].type = LittleLong (bsp->dplanes[i].type);
|
|
}
|
|
|
|
//
|
|
// texinfos
|
|
//
|
|
for (i=0 ; i<bsp->numtexinfo ; i++)
|
|
{
|
|
for (j=0 ; j<4 ; j++)
|
|
{
|
|
bsp->texinfo[i].vecs[0][j] = LittleFloat(bsp->texinfo[i].vecs[0][j]);
|
|
bsp->texinfo[i].vecs[1][j] = LittleFloat(bsp->texinfo[i].vecs[1][j]);
|
|
}
|
|
bsp->texinfo[i].flags = LittleLong (bsp->texinfo[i].flags);
|
|
bsp->texinfo[i].value = LittleLong (bsp->texinfo[i].value);
|
|
bsp->texinfo[i].nexttexinfo = LittleLong (bsp->texinfo[i].nexttexinfo);
|
|
}
|
|
|
|
//
|
|
// faces
|
|
//
|
|
for (i=0 ; i<bsp->numfaces ; i++)
|
|
{
|
|
bsp->dfaces[i].texinfo = LittleShort (bsp->dfaces[i].texinfo);
|
|
bsp->dfaces[i].planenum = LittleShort (bsp->dfaces[i].planenum);
|
|
bsp->dfaces[i].side = LittleShort (bsp->dfaces[i].side);
|
|
bsp->dfaces[i].lightofs = LittleLong (bsp->dfaces[i].lightofs);
|
|
bsp->dfaces[i].firstedge = LittleLong (bsp->dfaces[i].firstedge);
|
|
bsp->dfaces[i].numedges = LittleShort (bsp->dfaces[i].numedges);
|
|
}
|
|
|
|
//
|
|
// nodes
|
|
//
|
|
for (i=0 ; i<bsp->numnodes ; i++)
|
|
{
|
|
bsp->dnodes[i].planenum = LittleLong (bsp->dnodes[i].planenum);
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
bsp->dnodes[i].mins[j] = LittleShort (bsp->dnodes[i].mins[j]);
|
|
bsp->dnodes[i].maxs[j] = LittleShort (bsp->dnodes[i].maxs[j]);
|
|
}
|
|
bsp->dnodes[i].children[0] = LittleLong (bsp->dnodes[i].children[0]);
|
|
bsp->dnodes[i].children[1] = LittleLong (bsp->dnodes[i].children[1]);
|
|
bsp->dnodes[i].firstface = LittleShort (bsp->dnodes[i].firstface);
|
|
bsp->dnodes[i].numfaces = LittleShort (bsp->dnodes[i].numfaces);
|
|
}
|
|
|
|
//
|
|
// leafs
|
|
//
|
|
for (i=0 ; i<bsp->numleafs ; i++)
|
|
{
|
|
bsp->dleafs[i].contents = LittleLong (bsp->dleafs[i].contents);
|
|
bsp->dleafs[i].cluster = LittleShort (bsp->dleafs[i].cluster);
|
|
bsp->dleafs[i].area = LittleShort (bsp->dleafs[i].area);
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
bsp->dleafs[i].mins[j] = LittleShort (bsp->dleafs[i].mins[j]);
|
|
bsp->dleafs[i].maxs[j] = LittleShort (bsp->dleafs[i].maxs[j]);
|
|
}
|
|
|
|
bsp->dleafs[i].firstleafface = LittleShort (bsp->dleafs[i].firstleafface);
|
|
bsp->dleafs[i].numleaffaces = LittleShort (bsp->dleafs[i].numleaffaces);
|
|
bsp->dleafs[i].firstleafbrush = LittleShort (bsp->dleafs[i].firstleafbrush);
|
|
bsp->dleafs[i].numleafbrushes = LittleShort (bsp->dleafs[i].numleafbrushes);
|
|
}
|
|
|
|
//
|
|
// leaffaces
|
|
//
|
|
for (i=0 ; i<bsp->numleaffaces ; i++)
|
|
bsp->dleaffaces[i] = LittleShort (bsp->dleaffaces[i]);
|
|
|
|
//
|
|
// leafbrushes
|
|
//
|
|
for (i=0 ; i<bsp->numleafbrushes ; i++)
|
|
bsp->dleafbrushes[i] = LittleShort (bsp->dleafbrushes[i]);
|
|
|
|
//
|
|
// surfedges
|
|
//
|
|
for (i=0 ; i<bsp->numsurfedges ; i++)
|
|
bsp->dsurfedges[i] = LittleLong (bsp->dsurfedges[i]);
|
|
|
|
//
|
|
// edges
|
|
//
|
|
for (i=0 ; i<bsp->numedges ; i++)
|
|
{
|
|
bsp->dedges[i].v[0] = LittleShort (bsp->dedges[i].v[0]);
|
|
bsp->dedges[i].v[1] = LittleShort (bsp->dedges[i].v[1]);
|
|
}
|
|
|
|
//
|
|
// brushes
|
|
//
|
|
for (i=0 ; i<bsp->numbrushes ; i++)
|
|
{
|
|
bsp->dbrushes[i].firstside = LittleLong (bsp->dbrushes[i].firstside);
|
|
bsp->dbrushes[i].numsides = LittleLong (bsp->dbrushes[i].numsides);
|
|
bsp->dbrushes[i].contents = LittleLong (bsp->dbrushes[i].contents);
|
|
}
|
|
|
|
//
|
|
// areas
|
|
//
|
|
for (i=0 ; i<bsp->numareas ; i++)
|
|
{
|
|
bsp->dareas[i].numareaportals = LittleLong (bsp->dareas[i].numareaportals);
|
|
bsp->dareas[i].firstareaportal = LittleLong (bsp->dareas[i].firstareaportal);
|
|
}
|
|
|
|
//
|
|
// areasportals
|
|
//
|
|
for (i=0 ; i<bsp->numareaportals ; i++)
|
|
{
|
|
bsp->dareaportals[i].portalnum = LittleLong (bsp->dareaportals[i].portalnum);
|
|
bsp->dareaportals[i].otherarea = LittleLong (bsp->dareaportals[i].otherarea);
|
|
}
|
|
|
|
//
|
|
// brushsides
|
|
//
|
|
for (i=0 ; i<bsp->numbrushsides ; i++)
|
|
{
|
|
bsp->dbrushsides[i].planenum = LittleShort (bsp->dbrushsides[i].planenum);
|
|
bsp->dbrushsides[i].texinfo = LittleShort (bsp->dbrushsides[i].texinfo);
|
|
}
|
|
|
|
//
|
|
// visibility
|
|
//
|
|
if (todisk)
|
|
j = bsp->dvis->numclusters;
|
|
else
|
|
j = LittleLong(bsp->dvis->numclusters);
|
|
bsp->dvis->numclusters = LittleLong (bsp->dvis->numclusters);
|
|
for (i=0 ; i<j ; i++)
|
|
{
|
|
bsp->dvis->bitofs[i][0] = LittleLong (bsp->dvis->bitofs[i][0]);
|
|
bsp->dvis->bitofs[i][1] = LittleLong (bsp->dvis->bitofs[i][1]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
=============
|
|
Q2_Qbism_SwapBSPFile
|
|
|
|
Byte swaps all data in a bsp file.
|
|
=============
|
|
*/
|
|
void Q2_Qbism_SwapBSPFile (q2bsp_qbism_t *bsp, qboolean todisk)
|
|
{
|
|
int i, j;
|
|
q2_dmodel_t *d;
|
|
|
|
|
|
// models
|
|
for (i=0 ; i<bsp->nummodels ; i++)
|
|
{
|
|
d = &bsp->dmodels[i];
|
|
|
|
d->firstface = LittleLong (d->firstface);
|
|
d->numfaces = LittleLong (d->numfaces);
|
|
d->headnode = LittleLong (d->headnode);
|
|
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
d->mins[j] = LittleFloat(d->mins[j]);
|
|
d->maxs[j] = LittleFloat(d->maxs[j]);
|
|
d->origin[j] = LittleFloat(d->origin[j]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// vertexes
|
|
//
|
|
for (i=0 ; i<bsp->numvertexes ; i++)
|
|
{
|
|
for (j=0 ; j<3 ; j++)
|
|
bsp->dvertexes[i].point[j] = LittleFloat (bsp->dvertexes[i].point[j]);
|
|
}
|
|
|
|
//
|
|
// planes
|
|
//
|
|
for (i=0 ; i<bsp->numplanes ; i++)
|
|
{
|
|
for (j=0 ; j<3 ; j++)
|
|
bsp->dplanes[i].normal[j] = LittleFloat (bsp->dplanes[i].normal[j]);
|
|
bsp->dplanes[i].dist = LittleFloat (bsp->dplanes[i].dist);
|
|
bsp->dplanes[i].type = LittleLong (bsp->dplanes[i].type);
|
|
}
|
|
|
|
//
|
|
// texinfos
|
|
//
|
|
for (i=0 ; i<bsp->numtexinfo ; i++)
|
|
{
|
|
for (j=0 ; j<4 ; j++)
|
|
{
|
|
bsp->texinfo[i].vecs[0][j] = LittleFloat(bsp->texinfo[i].vecs[0][j]);
|
|
bsp->texinfo[i].vecs[1][j] = LittleFloat(bsp->texinfo[i].vecs[1][j]);
|
|
}
|
|
bsp->texinfo[i].flags = LittleLong (bsp->texinfo[i].flags);
|
|
bsp->texinfo[i].value = LittleLong (bsp->texinfo[i].value);
|
|
bsp->texinfo[i].nexttexinfo = LittleLong (bsp->texinfo[i].nexttexinfo);
|
|
}
|
|
|
|
//
|
|
// faces
|
|
//
|
|
for (i=0 ; i<bsp->numfaces ; i++)
|
|
{
|
|
bsp->dfaces[i].texinfo = LittleLong (bsp->dfaces[i].texinfo);
|
|
bsp->dfaces[i].planenum = LittleLong (bsp->dfaces[i].planenum);
|
|
bsp->dfaces[i].side = LittleLong (bsp->dfaces[i].side);
|
|
bsp->dfaces[i].lightofs = LittleLong (bsp->dfaces[i].lightofs);
|
|
bsp->dfaces[i].firstedge = LittleLong (bsp->dfaces[i].firstedge);
|
|
bsp->dfaces[i].numedges = LittleLong (bsp->dfaces[i].numedges);
|
|
}
|
|
|
|
//
|
|
// nodes
|
|
//
|
|
for (i=0 ; i<bsp->numnodes ; i++)
|
|
{
|
|
bsp->dnodes[i].planenum = LittleLong (bsp->dnodes[i].planenum);
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
bsp->dnodes[i].mins[j] = LittleFloat (bsp->dnodes[i].mins[j]);
|
|
bsp->dnodes[i].maxs[j] = LittleFloat (bsp->dnodes[i].maxs[j]);
|
|
}
|
|
bsp->dnodes[i].children[0] = LittleLong (bsp->dnodes[i].children[0]);
|
|
bsp->dnodes[i].children[1] = LittleLong (bsp->dnodes[i].children[1]);
|
|
bsp->dnodes[i].firstface = LittleLong (bsp->dnodes[i].firstface);
|
|
bsp->dnodes[i].numfaces = LittleLong (bsp->dnodes[i].numfaces);
|
|
}
|
|
|
|
//
|
|
// leafs
|
|
//
|
|
for (i=0 ; i<bsp->numleafs ; i++)
|
|
{
|
|
bsp->dleafs[i].contents = LittleLong (bsp->dleafs[i].contents);
|
|
bsp->dleafs[i].cluster = LittleLong (bsp->dleafs[i].cluster);
|
|
bsp->dleafs[i].area = LittleLong (bsp->dleafs[i].area);
|
|
for (j=0 ; j<3 ; j++)
|
|
{
|
|
bsp->dleafs[i].mins[j] = LittleFloat (bsp->dleafs[i].mins[j]);
|
|
bsp->dleafs[i].maxs[j] = LittleFloat (bsp->dleafs[i].maxs[j]);
|
|
}
|
|
|
|
bsp->dleafs[i].firstleafface = LittleLong (bsp->dleafs[i].firstleafface);
|
|
bsp->dleafs[i].numleaffaces = LittleLong (bsp->dleafs[i].numleaffaces);
|
|
bsp->dleafs[i].firstleafbrush = LittleLong (bsp->dleafs[i].firstleafbrush);
|
|
bsp->dleafs[i].numleafbrushes = LittleLong (bsp->dleafs[i].numleafbrushes);
|
|
}
|
|
|
|
//
|
|
// leaffaces
|
|
//
|
|
for (i=0 ; i<bsp->numleaffaces ; i++)
|
|
bsp->dleaffaces[i] = LittleLong (bsp->dleaffaces[i]);
|
|
|
|
//
|
|
// leafbrushes
|
|
//
|
|
for (i=0 ; i<bsp->numleafbrushes ; i++)
|
|
bsp->dleafbrushes[i] = LittleLong (bsp->dleafbrushes[i]);
|
|
|
|
//
|
|
// surfedges
|
|
//
|
|
for (i=0 ; i<bsp->numsurfedges ; i++)
|
|
bsp->dsurfedges[i] = LittleLong (bsp->dsurfedges[i]);
|
|
|
|
//
|
|
// edges
|
|
//
|
|
for (i=0 ; i<bsp->numedges ; i++)
|
|
{
|
|
bsp->dedges[i].v[0] = LittleLong (bsp->dedges[i].v[0]);
|
|
bsp->dedges[i].v[1] = LittleLong (bsp->dedges[i].v[1]);
|
|
}
|
|
|
|
//
|
|
// brushes
|
|
//
|
|
for (i=0 ; i<bsp->numbrushes ; i++)
|
|
{
|
|
bsp->dbrushes[i].firstside = LittleLong (bsp->dbrushes[i].firstside);
|
|
bsp->dbrushes[i].numsides = LittleLong (bsp->dbrushes[i].numsides);
|
|
bsp->dbrushes[i].contents = LittleLong (bsp->dbrushes[i].contents);
|
|
}
|
|
|
|
//
|
|
// areas
|
|
//
|
|
for (i=0 ; i<bsp->numareas ; i++)
|
|
{
|
|
bsp->dareas[i].numareaportals = LittleLong (bsp->dareas[i].numareaportals);
|
|
bsp->dareas[i].firstareaportal = LittleLong (bsp->dareas[i].firstareaportal);
|
|
}
|
|
|
|
//
|
|
// areasportals
|
|
//
|
|
for (i=0 ; i<bsp->numareaportals ; i++)
|
|
{
|
|
bsp->dareaportals[i].portalnum = LittleLong (bsp->dareaportals[i].portalnum);
|
|
bsp->dareaportals[i].otherarea = LittleLong (bsp->dareaportals[i].otherarea);
|
|
}
|
|
|
|
//
|
|
// brushsides
|
|
//
|
|
for (i=0 ; i<bsp->numbrushsides ; i++)
|
|
{
|
|
bsp->dbrushsides[i].planenum = LittleLong (bsp->dbrushsides[i].planenum);
|
|
bsp->dbrushsides[i].texinfo = LittleLong (bsp->dbrushsides[i].texinfo);
|
|
}
|
|
|
|
//
|
|
// visibility
|
|
//
|
|
if (todisk)
|
|
j = bsp->dvis->numclusters;
|
|
else
|
|
j = LittleLong(bsp->dvis->numclusters);
|
|
bsp->dvis->numclusters = LittleLong (bsp->dvis->numclusters);
|
|
for (i=0 ; i<j ; i++)
|
|
{
|
|
bsp->dvis->bitofs[i][0] = LittleLong (bsp->dvis->bitofs[i][0]);
|
|
bsp->dvis->bitofs[i][1] = LittleLong (bsp->dvis->bitofs[i][1]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* =============
|
|
* SwapBSPFile
|
|
* Byte swaps all data in a bsp file.
|
|
* =============
|
|
*/
|
|
static void
|
|
SwapBSPFile(bspdata_t *bspdata, swaptype_t swap)
|
|
{
|
|
if (bspdata->version == &bspver_q2) {
|
|
q2bsp_t *bsp = &bspdata->data.q2bsp;
|
|
Q2_SwapBSPFile(bsp, swap == TO_DISK);
|
|
return;
|
|
} else if (bspdata->version == &bspver_qbism) {
|
|
q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism;
|
|
Q2_Qbism_SwapBSPFile(bsp, swap == TO_DISK);
|
|
return;
|
|
}
|
|
|
|
if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) {
|
|
bsp29_t *bsp = &bspdata->data.bsp29;
|
|
|
|
SwapBSPVertexes(bsp->numvertexes, bsp->dvertexes);
|
|
SwapBSPPlanes(bsp->numplanes, bsp->dplanes);
|
|
SwapBSPTexinfo(bsp->numtexinfo, bsp->texinfo);
|
|
SwapBSP29Faces(bsp->numfaces, bsp->dfaces);
|
|
SwapBSP29Nodes(bsp->numnodes, bsp->dnodes);
|
|
SwapBSP29Leafs(bsp->numleafs, bsp->dleafs);
|
|
SwapBSP29Clipnodes(bsp->numclipnodes, bsp->dclipnodes);
|
|
SwapBSPMiptex(bsp->texdatasize, bsp->dtexdata, swap);
|
|
SwapBSP29Marksurfaces(bsp->nummarksurfaces, bsp->dmarksurfaces);
|
|
SwapBSPSurfedges(bsp->numsurfedges, bsp->dsurfedges);
|
|
SwapBSP29Edges(bsp->numedges, bsp->dedges);
|
|
SwapBSPModels(bsp->nummodels, bsp->dmodels);
|
|
|
|
return;
|
|
}
|
|
|
|
if (bspdata->version == &bspver_bsp2rmq) {
|
|
bsp2rmq_t *bsp = &bspdata->data.bsp2rmq;
|
|
|
|
SwapBSPVertexes(bsp->numvertexes, bsp->dvertexes);
|
|
SwapBSPPlanes(bsp->numplanes, bsp->dplanes);
|
|
SwapBSPTexinfo(bsp->numtexinfo, bsp->texinfo);
|
|
SwapBSP2Faces(bsp->numfaces, bsp->dfaces);
|
|
SwapBSP2rmqNodes(bsp->numnodes, bsp->dnodes);
|
|
SwapBSP2rmqLeafs(bsp->numleafs, bsp->dleafs);
|
|
SwapBSP2Clipnodes(bsp->numclipnodes, bsp->dclipnodes);
|
|
SwapBSPMiptex(bsp->texdatasize, bsp->dtexdata, swap);
|
|
SwapBSP2Marksurfaces(bsp->nummarksurfaces, bsp->dmarksurfaces);
|
|
SwapBSPSurfedges(bsp->numsurfedges, bsp->dsurfedges);
|
|
SwapBSP2Edges(bsp->numedges, bsp->dedges);
|
|
SwapBSPModels(bsp->nummodels, bsp->dmodels);
|
|
|
|
return;
|
|
}
|
|
|
|
if (bspdata->version == &bspver_bsp2) {
|
|
bsp2_t *bsp = &bspdata->data.bsp2;
|
|
|
|
SwapBSPVertexes(bsp->numvertexes, bsp->dvertexes);
|
|
SwapBSPPlanes(bsp->numplanes, bsp->dplanes);
|
|
SwapBSPTexinfo(bsp->numtexinfo, bsp->texinfo);
|
|
SwapBSP2Faces(bsp->numfaces, bsp->dfaces);
|
|
SwapBSP2Nodes(bsp->numnodes, bsp->dnodes);
|
|
SwapBSP2Leafs(bsp->numleafs, bsp->dleafs);
|
|
SwapBSP2Clipnodes(bsp->numclipnodes, bsp->dclipnodes);
|
|
SwapBSPMiptex(bsp->texdatasize, bsp->dtexdata, swap);
|
|
SwapBSP2Marksurfaces(bsp->nummarksurfaces, bsp->dmarksurfaces);
|
|
SwapBSPSurfedges(bsp->numsurfedges, bsp->dsurfedges);
|
|
SwapBSP2Edges(bsp->numedges, bsp->dedges);
|
|
SwapBSPModels(bsp->nummodels, bsp->dmodels);
|
|
|
|
return;
|
|
}
|
|
|
|
Error("Unsupported BSP version: %d", bspdata->version);
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (ver. 29 <-> MBSP)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static mleaf_t *
|
|
BSP29toM_Leafs(const bsp29_dleaf_t *dleafs29, int numleafs) {
|
|
const bsp29_dleaf_t *dleaf29 = dleafs29;
|
|
mleaf_t *newdata, *mleaf;
|
|
int i, j;
|
|
|
|
newdata = mleaf = (mleaf_t *)calloc(numleafs, sizeof(*mleaf));
|
|
|
|
for (i = 0; i < numleafs; i++, dleaf29++, mleaf++) {
|
|
mleaf->contents = dleaf29->contents;
|
|
mleaf->visofs = dleaf29->visofs;
|
|
for (j = 0; j < 3; j++) {
|
|
mleaf->mins[j] = dleaf29->mins[j];
|
|
mleaf->maxs[j] = dleaf29->maxs[j];
|
|
}
|
|
mleaf->firstmarksurface = dleaf29->firstmarksurface;
|
|
mleaf->nummarksurfaces = dleaf29->nummarksurfaces;
|
|
for (j = 0; j < NUM_AMBIENTS; j++)
|
|
mleaf->ambient_level[j] = dleaf29->ambient_level[j];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp29_dleaf_t *
|
|
MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) {
|
|
const mleaf_t *mleaf = mleafs;
|
|
bsp29_dleaf_t *newdata, *dleaf29;
|
|
int i, j;
|
|
|
|
newdata = dleaf29 = (bsp29_dleaf_t *)calloc(numleafs, sizeof(*dleaf29));
|
|
|
|
for (i = 0; i < numleafs; i++, mleaf++, dleaf29++) {
|
|
dleaf29->contents = mleaf->contents;
|
|
dleaf29->visofs = mleaf->visofs;
|
|
for (j = 0; j < 3; j++) {
|
|
dleaf29->mins[j] = mleaf->mins[j];
|
|
dleaf29->maxs[j] = mleaf->maxs[j];
|
|
}
|
|
dleaf29->firstmarksurface = mleaf->firstmarksurface;
|
|
dleaf29->nummarksurfaces = mleaf->nummarksurfaces;
|
|
for (j = 0; j < NUM_AMBIENTS; j++)
|
|
dleaf29->ambient_level[j] = mleaf->ambient_level[j];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static gtexinfo_t *
|
|
BSP29toM_Texinfo(const texinfo_t *texinfos, int numtexinfo) {
|
|
const texinfo_t *texinfo29 = texinfos;
|
|
gtexinfo_t *newdata, *mtexinfo;
|
|
int i, j, k;
|
|
|
|
newdata = mtexinfo = (gtexinfo_t *)calloc(numtexinfo, sizeof(*mtexinfo));
|
|
|
|
for (i = 0; i < numtexinfo; i++, texinfo29++, mtexinfo++) {
|
|
for (j=0; j<2; j++)
|
|
for (k=0; k<4; k++)
|
|
mtexinfo->vecs[j][k] = texinfo29->vecs[j][k];
|
|
mtexinfo->flags = texinfo29->flags;
|
|
mtexinfo->miptex = texinfo29->miptex;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static texinfo_t *
|
|
MBSPto29_Texinfo(const gtexinfo_t *mtexinfos, int numtexinfo) {
|
|
const gtexinfo_t *mtexinfo = mtexinfos;
|
|
texinfo_t *newdata, *texinfo29;
|
|
int i, j, k;
|
|
|
|
newdata = texinfo29 = (texinfo_t *)calloc(numtexinfo, sizeof(*texinfo29));
|
|
|
|
for (i = 0; i < numtexinfo; i++, texinfo29++, mtexinfo++) {
|
|
for (j=0; j<2; j++)
|
|
for (k=0; k<4; k++)
|
|
texinfo29->vecs[j][k] = mtexinfo->vecs[j][k];
|
|
texinfo29->flags = mtexinfo->flags;
|
|
texinfo29->miptex = mtexinfo->miptex;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (ver. q2 <-> MBSP)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static dmodelh2_t *
|
|
Q2BSPtoM_Models(const q2_dmodel_t *dmodelsq2, int nummodels) {
|
|
const q2_dmodel_t *dmodelq2 = dmodelsq2;
|
|
dmodelh2_t *newdata, *dmodelh2;
|
|
int i, j;
|
|
|
|
newdata = dmodelh2 = (dmodelh2_t *)calloc(nummodels, sizeof(*dmodelh2));
|
|
|
|
for (i = 0; i < nummodels; i++, dmodelq2++, dmodelh2++) {
|
|
for (j = 0; j<3; j++) {
|
|
dmodelh2->mins[j] = dmodelq2->mins[j];
|
|
dmodelh2->maxs[j] = dmodelq2->maxs[j];
|
|
dmodelh2->origin[j] = dmodelq2->origin[j];
|
|
}
|
|
dmodelh2->headnode[0] = dmodelq2->headnode;
|
|
dmodelh2->visleafs = 0;
|
|
dmodelh2->firstface = dmodelq2->firstface;
|
|
dmodelh2->numfaces = dmodelq2->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dmodel_t *
|
|
MBSPtoQ2_Models(const dmodelh2_t *dmodelsh2, int nummodels) {
|
|
const dmodelh2_t *dmodelh2 = dmodelsh2;
|
|
q2_dmodel_t *newdata, *dmodelq2;
|
|
int i, j;
|
|
|
|
newdata = dmodelq2 = (q2_dmodel_t *)calloc(nummodels, sizeof(*dmodelq2));
|
|
|
|
for (i = 0; i < nummodels; i++, dmodelh2++, dmodelq2++) {
|
|
for (j = 0; j<3; j++) {
|
|
dmodelq2->mins[j] = dmodelh2->mins[j];
|
|
dmodelq2->maxs[j] = dmodelh2->maxs[j];
|
|
dmodelq2->origin[j] = dmodelh2->origin[j];
|
|
}
|
|
dmodelq2->headnode = dmodelh2->headnode[0];
|
|
dmodelq2->firstface = dmodelh2->firstface;
|
|
dmodelq2->numfaces = dmodelh2->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static mleaf_t *
|
|
Q2BSPtoM_Leafs(const q2_dleaf_t *dleafsq2, int numleafs) {
|
|
const q2_dleaf_t *dleafq2 = dleafsq2;
|
|
mleaf_t *newdata, *mleaf;
|
|
int i, j;
|
|
|
|
newdata = mleaf = (mleaf_t *)calloc(numleafs, sizeof(*mleaf));
|
|
|
|
for (i = 0; i < numleafs; i++, dleafq2++, mleaf++) {
|
|
mleaf->contents = dleafq2->contents;
|
|
mleaf->cluster = dleafq2->cluster;
|
|
mleaf->area = dleafq2->area;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
mleaf->mins[j] = dleafq2->mins[j];
|
|
mleaf->maxs[j] = dleafq2->maxs[j];
|
|
}
|
|
mleaf->firstmarksurface = dleafq2->firstleafface;
|
|
mleaf->nummarksurfaces = dleafq2->numleaffaces;
|
|
|
|
mleaf->firstleafbrush = dleafq2->firstleafbrush;
|
|
mleaf->numleafbrushes = dleafq2->numleafbrushes;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static mleaf_t *
|
|
Q2BSP_QBSPtoM_Leafs(const q2_dleaf_qbism_t *dleafsq2, int numleafs) {
|
|
const q2_dleaf_qbism_t *dleafq2 = dleafsq2;
|
|
mleaf_t *newdata, *mleaf;
|
|
int i, j;
|
|
|
|
newdata = mleaf = (mleaf_t *)calloc(numleafs, sizeof(*mleaf));
|
|
|
|
for (i = 0; i < numleafs; i++, dleafq2++, mleaf++) {
|
|
mleaf->contents = dleafq2->contents;
|
|
mleaf->cluster = dleafq2->cluster;
|
|
mleaf->area = dleafq2->area;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
mleaf->mins[j] = dleafq2->mins[j];
|
|
mleaf->maxs[j] = dleafq2->maxs[j];
|
|
}
|
|
mleaf->firstmarksurface = dleafq2->firstleafface;
|
|
mleaf->nummarksurfaces = dleafq2->numleaffaces;
|
|
|
|
mleaf->firstleafbrush = dleafq2->firstleafbrush;
|
|
mleaf->numleafbrushes = dleafq2->numleafbrushes;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dleaf_t *
|
|
MBSPtoQ2_Leafs(const mleaf_t *mleafs, int numleafs) {
|
|
const mleaf_t *mleaf = mleafs;
|
|
q2_dleaf_t *newdata, *dleafq2;
|
|
int i, j;
|
|
|
|
newdata = dleafq2 = (q2_dleaf_t *)calloc(numleafs, sizeof(*dleafq2));
|
|
|
|
for (i = 0; i < numleafs; i++, mleaf++, dleafq2++) {
|
|
dleafq2->contents = mleaf->contents;
|
|
dleafq2->cluster = mleaf->cluster;
|
|
dleafq2->area = mleaf->area;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
dleafq2->mins[j] = mleaf->mins[j];
|
|
dleafq2->maxs[j] = mleaf->maxs[j];
|
|
}
|
|
dleafq2->firstleafface = mleaf->firstmarksurface;
|
|
dleafq2->numleaffaces = mleaf->nummarksurfaces;
|
|
|
|
dleafq2->firstleafbrush = mleaf->firstleafbrush;
|
|
dleafq2->numleafbrushes = mleaf->numleafbrushes;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dleaf_qbism_t *
|
|
MBSPtoQ2_Qbism_Leafs(const mleaf_t *mleafs, int numleafs) {
|
|
const mleaf_t *mleaf = mleafs;
|
|
q2_dleaf_qbism_t *newdata, *dleafq2;
|
|
int i, j;
|
|
|
|
newdata = dleafq2 = (q2_dleaf_qbism_t *)calloc(numleafs, sizeof(*dleafq2));
|
|
|
|
for (i = 0; i < numleafs; i++, mleaf++, dleafq2++) {
|
|
dleafq2->contents = mleaf->contents;
|
|
dleafq2->cluster = mleaf->cluster;
|
|
dleafq2->area = mleaf->area;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
dleafq2->mins[j] = mleaf->mins[j];
|
|
dleafq2->maxs[j] = mleaf->maxs[j];
|
|
}
|
|
dleafq2->firstleafface = mleaf->firstmarksurface;
|
|
dleafq2->numleaffaces = mleaf->nummarksurfaces;
|
|
|
|
dleafq2->firstleafbrush = mleaf->firstleafbrush;
|
|
dleafq2->numleafbrushes = mleaf->numleafbrushes;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dnode_t *
|
|
Q2BSPto2_Nodes(const q2_dnode_t *dnodesq2, int numnodes) {
|
|
const q2_dnode_t *dnodeq2 = dnodesq2;
|
|
bsp2_dnode_t *newdata, *dnode2;
|
|
int i, j;
|
|
|
|
newdata = dnode2 = static_cast<bsp2_dnode_t *>(malloc(numnodes * sizeof(*dnode2)));
|
|
|
|
for (i = 0; i < numnodes; i++, dnodeq2++, dnode2++) {
|
|
dnode2->planenum = dnodeq2->planenum;
|
|
dnode2->children[0] = dnodeq2->children[0];
|
|
dnode2->children[1] = dnodeq2->children[1];
|
|
for (j = 0; j < 3; j++) {
|
|
dnode2->mins[j] = dnodeq2->mins[j];
|
|
dnode2->maxs[j] = dnodeq2->maxs[j];
|
|
}
|
|
dnode2->firstface = dnodeq2->firstface;
|
|
dnode2->numfaces = dnodeq2->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dnode_t *
|
|
BSP2toQ2_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
|
|
const bsp2_dnode_t *dnode2 = dnodes2;
|
|
q2_dnode_t *newdata, *dnodeq2;
|
|
int i, j;
|
|
|
|
newdata = dnodeq2 = static_cast<q2_dnode_t *>(malloc(numnodes * sizeof(*dnodeq2)));
|
|
|
|
for (i = 0; i < numnodes; i++, dnode2++, dnodeq2++) {
|
|
dnodeq2->planenum = dnode2->planenum;
|
|
dnodeq2->children[0] = dnode2->children[0];
|
|
dnodeq2->children[1] = dnode2->children[1];
|
|
for (j = 0; j < 3; j++) {
|
|
dnodeq2->mins[j] = dnode2->mins[j];
|
|
dnodeq2->maxs[j] = dnode2->maxs[j];
|
|
}
|
|
dnodeq2->firstface = dnode2->firstface;
|
|
dnodeq2->numfaces = dnode2->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dface_t *
|
|
Q2BSPto2_Faces(const q2_dface_t *dfacesq2, int numfaces) {
|
|
const q2_dface_t *dfaceq2 = dfacesq2;
|
|
bsp2_dface_t *newdata, *dface2;
|
|
int i, j;
|
|
|
|
newdata = dface2 = static_cast<bsp2_dface_t *>(malloc(numfaces * sizeof(*dface2)));
|
|
|
|
for (i = 0; i < numfaces; i++, dfaceq2++, dface2++) {
|
|
dface2->planenum = dfaceq2->planenum;
|
|
dface2->side = dfaceq2->side;
|
|
dface2->firstedge = dfaceq2->firstedge;
|
|
dface2->numedges = dfaceq2->numedges;
|
|
dface2->texinfo = dfaceq2->texinfo;
|
|
for (j = 0; j < MAXLIGHTMAPS; j++)
|
|
dface2->styles[j] = dfaceq2->styles[j];
|
|
dface2->lightofs = dfaceq2->lightofs;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dface_t *
|
|
Q2BSP_QBSPto2_Faces(const q2_dface_qbism_t *dfacesq2, int numfaces) {
|
|
const q2_dface_qbism_t *dfaceq2 = dfacesq2;
|
|
bsp2_dface_t *newdata, *dface2;
|
|
int i, j;
|
|
|
|
newdata = dface2 = static_cast<bsp2_dface_t *>(malloc(numfaces * sizeof(*dface2)));
|
|
|
|
for (i = 0; i < numfaces; i++, dfaceq2++, dface2++) {
|
|
dface2->planenum = dfaceq2->planenum;
|
|
dface2->side = dfaceq2->side;
|
|
dface2->firstedge = dfaceq2->firstedge;
|
|
dface2->numedges = dfaceq2->numedges;
|
|
dface2->texinfo = dfaceq2->texinfo;
|
|
for (j = 0; j < MAXLIGHTMAPS; j++)
|
|
dface2->styles[j] = dfaceq2->styles[j];
|
|
dface2->lightofs = dfaceq2->lightofs;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dface_t *
|
|
BSP2toQ2_Faces(const bsp2_dface_t *dfaces2, int numfaces) {
|
|
const bsp2_dface_t *dface2 = dfaces2;
|
|
q2_dface_t *newdata, *dfaceq2;
|
|
int i, j;
|
|
|
|
newdata = dfaceq2 = static_cast<q2_dface_t *>(malloc(numfaces * sizeof(*dfaceq2)));
|
|
|
|
for (i = 0; i < numfaces; i++, dface2++, dfaceq2++) {
|
|
dfaceq2->planenum = dface2->planenum;
|
|
dfaceq2->side = dface2->side;
|
|
dfaceq2->firstedge = dface2->firstedge;
|
|
dfaceq2->numedges = dface2->numedges;
|
|
dfaceq2->texinfo = dface2->texinfo;
|
|
for (j = 0; j < MAXLIGHTMAPS; j++)
|
|
dfaceq2->styles[j] = dface2->styles[j];
|
|
dfaceq2->lightofs = dface2->lightofs;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dface_qbism_t *
|
|
BSP2toQ2_Qbism_Faces(const bsp2_dface_t *dfaces2, int numfaces) {
|
|
const bsp2_dface_t *dface2 = dfaces2;
|
|
q2_dface_qbism_t *newdata, *dfaceq2;
|
|
int i, j;
|
|
|
|
newdata = dfaceq2 = static_cast<q2_dface_qbism_t *>(malloc(numfaces * sizeof(*dfaceq2)));
|
|
|
|
for (i = 0; i < numfaces; i++, dface2++, dfaceq2++) {
|
|
dfaceq2->planenum = dface2->planenum;
|
|
dfaceq2->side = dface2->side;
|
|
dfaceq2->firstedge = dface2->firstedge;
|
|
dfaceq2->numedges = dface2->numedges;
|
|
dfaceq2->texinfo = dface2->texinfo;
|
|
for (j = 0; j < MAXLIGHTMAPS; j++)
|
|
dfaceq2->styles[j] = dface2->styles[j];
|
|
dfaceq2->lightofs = dface2->lightofs;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static gtexinfo_t *
|
|
Q2BSPtoM_Texinfo(const q2_texinfo_t *dtexinfosq2, int numtexinfos) {
|
|
const q2_texinfo_t *dtexinfoq2 = dtexinfosq2;
|
|
gtexinfo_t *newdata, *dtexinfo2;
|
|
int i, j, k;
|
|
|
|
newdata = dtexinfo2 = static_cast<gtexinfo_t *>(malloc(numtexinfos * sizeof(*dtexinfo2)));
|
|
|
|
for (i = 0; i < numtexinfos; i++, dtexinfoq2++, dtexinfo2++) {
|
|
for (j = 0; j < 2; j++)
|
|
for (k = 0; k < 4; k++)
|
|
dtexinfo2->vecs[j][k] = dtexinfoq2->vecs[j][k];
|
|
dtexinfo2->flags = dtexinfoq2->flags;
|
|
memcpy(dtexinfo2->texture, dtexinfoq2->texture, sizeof(dtexinfo2->texture));
|
|
dtexinfo2->value = dtexinfoq2->value;
|
|
dtexinfo2->nexttexinfo = dtexinfoq2->nexttexinfo;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_texinfo_t *
|
|
MBSPtoQ2_Texinfo(const gtexinfo_t *dtexinfos2, int numtexinfos) {
|
|
const gtexinfo_t *dtexinfo2 = dtexinfos2;
|
|
q2_texinfo_t *newdata, *dtexinfoq2;
|
|
int i, j, k;
|
|
|
|
newdata = dtexinfoq2 = static_cast<q2_texinfo_t *>(malloc(numtexinfos * sizeof(*dtexinfoq2)));
|
|
|
|
for (i = 0; i < numtexinfos; i++, dtexinfo2++, dtexinfoq2++) {
|
|
for (j = 0; j < 2; j++)
|
|
for (k = 0; k < 4; k++)
|
|
dtexinfoq2->vecs[j][k] = dtexinfo2->vecs[j][k];
|
|
dtexinfoq2->flags = dtexinfo2->flags;
|
|
memcpy(dtexinfoq2->texture, dtexinfo2->texture, sizeof(dtexinfo2->texture));
|
|
dtexinfoq2->value = dtexinfo2->value;
|
|
dtexinfoq2->nexttexinfo = dtexinfo2->nexttexinfo;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (ver. 2rmq <-> MBSP)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static mleaf_t *
|
|
BSP2rmqtoM_Leafs(const bsp2rmq_dleaf_t *dleafs2rmq, int numleafs) {
|
|
const bsp2rmq_dleaf_t *dleaf2rmq = dleafs2rmq;
|
|
mleaf_t *newdata, *mleaf;
|
|
int i, j;
|
|
|
|
newdata = mleaf = (mleaf_t *)calloc(numleafs, sizeof(*mleaf));
|
|
|
|
for (i = 0; i < numleafs; i++, dleaf2rmq++, mleaf++) {
|
|
mleaf->contents = dleaf2rmq->contents;
|
|
mleaf->visofs = dleaf2rmq->visofs;
|
|
for (j = 0; j < 3; j++) {
|
|
mleaf->mins[j] = dleaf2rmq->mins[j];
|
|
mleaf->maxs[j] = dleaf2rmq->maxs[j];
|
|
}
|
|
mleaf->firstmarksurface = dleaf2rmq->firstmarksurface;
|
|
mleaf->nummarksurfaces = dleaf2rmq->nummarksurfaces;
|
|
for (j = 0; j < NUM_AMBIENTS; j++)
|
|
mleaf->ambient_level[j] = dleaf2rmq->ambient_level[j];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2rmq_dleaf_t *
|
|
MBSPto2rmq_Leafs(const mleaf_t *mleafs, int numleafs) {
|
|
const mleaf_t *mleaf = mleafs;
|
|
bsp2rmq_dleaf_t *newdata, *dleaf2rmq;
|
|
int i, j;
|
|
|
|
newdata = dleaf2rmq = (bsp2rmq_dleaf_t *)calloc(numleafs, sizeof(*dleaf2rmq));
|
|
|
|
for (i = 0; i < numleafs; i++, mleaf++, dleaf2rmq++) {
|
|
dleaf2rmq->contents = mleaf->contents;
|
|
dleaf2rmq->visofs = mleaf->visofs;
|
|
for (j = 0; j < 3; j++) {
|
|
dleaf2rmq->mins[j] = mleaf->mins[j];
|
|
dleaf2rmq->maxs[j] = mleaf->maxs[j];
|
|
}
|
|
dleaf2rmq->firstmarksurface = mleaf->firstmarksurface;
|
|
dleaf2rmq->nummarksurfaces = mleaf->nummarksurfaces;
|
|
for (j = 0; j < NUM_AMBIENTS; j++)
|
|
dleaf2rmq->ambient_level[j] = mleaf->ambient_level[j];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (ver. 2 <-> MBSP)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static mleaf_t *
|
|
BSP2toM_Leafs(const bsp2_dleaf_t *dleafs2, int numleafs) {
|
|
const bsp2_dleaf_t *dleaf2 = dleafs2;
|
|
mleaf_t *newdata, *mleaf;
|
|
int i, j;
|
|
|
|
newdata = mleaf = (mleaf_t *)calloc(numleafs, sizeof(*mleaf));
|
|
|
|
for (i = 0; i < numleafs; i++, dleaf2++, mleaf++) {
|
|
mleaf->contents = dleaf2->contents;
|
|
mleaf->visofs = dleaf2->visofs;
|
|
for (j = 0; j < 3; j++) {
|
|
mleaf->mins[j] = dleaf2->mins[j];
|
|
mleaf->maxs[j] = dleaf2->maxs[j];
|
|
}
|
|
mleaf->firstmarksurface = dleaf2->firstmarksurface;
|
|
mleaf->nummarksurfaces = dleaf2->nummarksurfaces;
|
|
for (j = 0; j < NUM_AMBIENTS; j++)
|
|
mleaf->ambient_level[j] = dleaf2->ambient_level[j];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dleaf_t *
|
|
MBSPto2_Leafs(const mleaf_t *mleafs, int numleafs) {
|
|
const mleaf_t *mleaf = mleafs;
|
|
bsp2_dleaf_t *newdata, *dleaf2;
|
|
int i, j;
|
|
|
|
newdata = dleaf2 = (bsp2_dleaf_t *)calloc(numleafs, sizeof(*dleaf2));
|
|
|
|
for (i = 0; i < numleafs; i++, mleaf++, dleaf2++) {
|
|
dleaf2->contents = mleaf->contents;
|
|
dleaf2->visofs = mleaf->visofs;
|
|
for (j = 0; j < 3; j++) {
|
|
dleaf2->mins[j] = mleaf->mins[j];
|
|
dleaf2->maxs[j] = mleaf->maxs[j];
|
|
}
|
|
dleaf2->firstmarksurface = mleaf->firstmarksurface;
|
|
dleaf2->nummarksurfaces = mleaf->nummarksurfaces;
|
|
for (j = 0; j < NUM_AMBIENTS; j++)
|
|
dleaf2->ambient_level[j] = mleaf->ambient_level[j];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (ver. 29 <-> BSP2)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static bsp2_dnode_t *
|
|
BSP29to2_Nodes(const bsp29_dnode_t *dnodes29, int numnodes) {
|
|
const bsp29_dnode_t *dnode29 = dnodes29;
|
|
bsp2_dnode_t *newdata, *dnode2;
|
|
int i, j;
|
|
|
|
newdata = dnode2 = static_cast<bsp2_dnode_t *>(malloc(numnodes * sizeof(*dnode2)));
|
|
|
|
for (i = 0; i < numnodes; i++, dnode29++, dnode2++) {
|
|
dnode2->planenum = dnode29->planenum;
|
|
dnode2->children[0] = dnode29->children[0];
|
|
dnode2->children[1] = dnode29->children[1];
|
|
for (j = 0; j < 3; j++) {
|
|
dnode2->mins[j] = dnode29->mins[j];
|
|
dnode2->maxs[j] = dnode29->maxs[j];
|
|
}
|
|
dnode2->firstface = dnode29->firstface;
|
|
dnode2->numfaces = dnode29->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp29_dnode_t *
|
|
BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
|
|
const bsp2_dnode_t *dnode2 = dnodes2;
|
|
bsp29_dnode_t *newdata, *dnode29;
|
|
int i, j;
|
|
|
|
newdata = dnode29 = static_cast<bsp29_dnode_t *>(malloc(numnodes * sizeof(*dnode29)));
|
|
|
|
for (i = 0; i < numnodes; i++, dnode2++, dnode29++) {
|
|
dnode29->planenum = dnode2->planenum;
|
|
dnode29->children[0] = dnode2->children[0];
|
|
dnode29->children[1] = dnode2->children[1];
|
|
for (j = 0; j < 3; j++) {
|
|
dnode29->mins[j] = dnode2->mins[j];
|
|
dnode29->maxs[j] = dnode2->maxs[j];
|
|
}
|
|
dnode29->firstface = dnode2->firstface;
|
|
dnode29->numfaces = dnode2->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dface_t *
|
|
BSP29to2_Faces(const bsp29_dface_t *dfaces29, int numfaces) {
|
|
const bsp29_dface_t *dface29 = dfaces29;
|
|
bsp2_dface_t *newdata, *dface2;
|
|
int i, j;
|
|
|
|
newdata = dface2 = static_cast<bsp2_dface_t *>(malloc(numfaces * sizeof(*dface2)));
|
|
|
|
for (i = 0; i < numfaces; i++, dface29++, dface2++) {
|
|
dface2->planenum = dface29->planenum;
|
|
dface2->side = dface29->side;
|
|
dface2->firstedge = dface29->firstedge;
|
|
dface2->numedges = dface29->numedges;
|
|
dface2->texinfo = dface29->texinfo;
|
|
for (j = 0; j < MAXLIGHTMAPS; j++)
|
|
dface2->styles[j] = dface29->styles[j];
|
|
dface2->lightofs = dface29->lightofs;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp29_dface_t *
|
|
BSP2to29_Faces(const bsp2_dface_t *dfaces2, int numfaces) {
|
|
const bsp2_dface_t *dface2 = dfaces2;
|
|
bsp29_dface_t *newdata, *dface29;
|
|
int i, j;
|
|
|
|
newdata = dface29 = static_cast<bsp29_dface_t *>(malloc(numfaces * sizeof(*dface29)));
|
|
|
|
for (i = 0; i < numfaces; i++, dface2++, dface29++) {
|
|
dface29->planenum = dface2->planenum;
|
|
dface29->side = dface2->side;
|
|
dface29->firstedge = dface2->firstedge;
|
|
dface29->numedges = dface2->numedges;
|
|
dface29->texinfo = dface2->texinfo;
|
|
for (j = 0; j < MAXLIGHTMAPS; j++)
|
|
dface29->styles[j] = dface2->styles[j];
|
|
dface29->lightofs = dface2->lightofs;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dclipnode_t *
|
|
BSP29to2_Clipnodes(const bsp29_dclipnode_t *dclipnodes29, int numclipnodes) {
|
|
const bsp29_dclipnode_t *dclipnode29 = dclipnodes29;
|
|
bsp2_dclipnode_t *newdata, *dclipnode2;
|
|
int i, j;
|
|
|
|
newdata = dclipnode2 = static_cast<bsp2_dclipnode_t *>(malloc(numclipnodes * sizeof(*dclipnode2)));
|
|
|
|
for (i = 0; i < numclipnodes; i++, dclipnode29++, dclipnode2++) {
|
|
dclipnode2->planenum = dclipnode29->planenum;
|
|
for (j = 0; j < 2; j++) {
|
|
/* Slightly tricky since we support > 32k clipnodes */
|
|
int32_t child = (uint16_t)dclipnode29->children[j];
|
|
dclipnode2->children[j] = child > 0xfff0 ? child - 0x10000 : child;
|
|
}
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp29_dclipnode_t *
|
|
BSP2to29_Clipnodes(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) {
|
|
const bsp2_dclipnode_t *dclipnode2 = dclipnodes2;
|
|
bsp29_dclipnode_t *newdata, *dclipnode29;
|
|
int i, j;
|
|
|
|
newdata = dclipnode29 = static_cast<bsp29_dclipnode_t *>(malloc(numclipnodes * sizeof(*dclipnode29)));
|
|
|
|
for (i = 0; i < numclipnodes; i++, dclipnode2++, dclipnode29++) {
|
|
dclipnode29->planenum = dclipnode2->planenum;
|
|
for (j = 0; j < 2; j++) {
|
|
/* Slightly tricky since we support > 32k clipnodes */
|
|
int32_t child = dclipnode2->children[j];
|
|
dclipnode29->children[j] = child < 0 ? child + 0x10000 : child;
|
|
}
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2_dedge_t *
|
|
BSP29to2_Edges(const bsp29_dedge_t *dedges29, int numedges)
|
|
{
|
|
const bsp29_dedge_t *dedge29 = dedges29;
|
|
bsp2_dedge_t *newdata, *dedge2;
|
|
int i;
|
|
|
|
newdata = dedge2 = static_cast<bsp2_dedge_t *>(malloc(numedges * sizeof(*dedge2)));
|
|
|
|
for (i = 0; i < numedges; i++, dedge29++, dedge2++) {
|
|
dedge2->v[0] = dedge29->v[0];
|
|
dedge2->v[1] = dedge29->v[1];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp29_dedge_t *
|
|
BSP2to29_Edges(const bsp2_dedge_t *dedges2, int numedges)
|
|
{
|
|
const bsp2_dedge_t *dedge2 = dedges2;
|
|
bsp29_dedge_t *newdata, *dedge29;
|
|
int i;
|
|
|
|
newdata = dedge29 = static_cast<bsp29_dedge_t *>(malloc(numedges * sizeof(*dedge29)));
|
|
|
|
for (i = 0; i < numedges; i++, dedge2++, dedge29++) {
|
|
dedge29->v[0] = dedge2->v[0];
|
|
dedge29->v[1] = dedge2->v[1];
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static uint32_t *
|
|
BSP29to2_Marksurfaces(const uint16_t *dmarksurfaces29, int nummarksurfaces)
|
|
{
|
|
const uint16_t *dmarksurface29 = dmarksurfaces29;
|
|
uint32_t *newdata, *dmarksurface2;
|
|
int i;
|
|
|
|
newdata = dmarksurface2 = static_cast<uint32_t *>(malloc(nummarksurfaces * sizeof(*dmarksurface2)));
|
|
|
|
for (i = 0; i < nummarksurfaces; i++, dmarksurface29++, dmarksurface2++)
|
|
*dmarksurface2 = *dmarksurface29;
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static uint16_t *
|
|
BSP2to29_Marksurfaces(const uint32_t *dmarksurfaces2, int nummarksurfaces)
|
|
{
|
|
const uint32_t *dmarksurface2 = dmarksurfaces2;
|
|
uint16_t *newdata, *dmarksurface29;
|
|
int i;
|
|
|
|
newdata = dmarksurface29 = static_cast<uint16_t *>(malloc(nummarksurfaces * sizeof(*dmarksurface29)));
|
|
|
|
for (i = 0; i < nummarksurfaces; i++, dmarksurface2++, dmarksurface29++)
|
|
*dmarksurface29 = *dmarksurface2;
|
|
|
|
return newdata;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (ver. BSP2rmq <-> BSP2)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static bsp2_dnode_t *
|
|
BSP2rmqto2_Nodes(const bsp2rmq_dnode_t *dnodes2rmq, int numnodes) {
|
|
const bsp2rmq_dnode_t *dnode2rmq = dnodes2rmq;
|
|
bsp2_dnode_t *newdata, *dnode2;
|
|
int i, j;
|
|
|
|
newdata = dnode2 = static_cast<bsp2_dnode_t *>(malloc(numnodes * sizeof(*dnode2)));
|
|
|
|
for (i = 0; i < numnodes; i++, dnode2rmq++, dnode2++) {
|
|
dnode2->planenum = dnode2rmq->planenum;
|
|
dnode2->children[0] = dnode2rmq->children[0];
|
|
dnode2->children[1] = dnode2rmq->children[1];
|
|
for (j = 0; j < 3; j++) {
|
|
dnode2->mins[j] = dnode2rmq->mins[j];
|
|
dnode2->maxs[j] = dnode2rmq->maxs[j];
|
|
}
|
|
dnode2->firstface = dnode2rmq->firstface;
|
|
dnode2->numfaces = dnode2rmq->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static bsp2rmq_dnode_t *
|
|
BSP2to2rmq_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
|
|
const bsp2_dnode_t *dnode2 = dnodes2;
|
|
bsp2rmq_dnode_t *newdata, *dnode2rmq;
|
|
int i, j;
|
|
|
|
newdata = dnode2rmq = static_cast<bsp2rmq_dnode_t *>(malloc(numnodes * sizeof(*dnode2rmq)));
|
|
|
|
for (i = 0; i < numnodes; i++, dnode2++, dnode2rmq++) {
|
|
dnode2rmq->planenum = dnode2->planenum;
|
|
dnode2rmq->children[0] = dnode2->children[0];
|
|
dnode2rmq->children[1] = dnode2->children[1];
|
|
for (j = 0; j < 3; j++) {
|
|
dnode2rmq->mins[j] = dnode2->mins[j];
|
|
dnode2rmq->maxs[j] = dnode2->maxs[j];
|
|
}
|
|
dnode2rmq->firstface = dnode2->firstface;
|
|
dnode2rmq->numfaces = dnode2->numfaces;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* BSP Format Conversion (no-ops)
|
|
* =========================================================================
|
|
*/
|
|
|
|
static void *CopyArray(const void *in, int numelems, size_t elemsize)
|
|
{
|
|
void *out = (void *)calloc(numelems, elemsize);
|
|
memcpy(out, in, numelems * elemsize);
|
|
return out;
|
|
}
|
|
|
|
static dmodel_t *BSP29_CopyModels(const dmodel_t *dmodels, int nummodels)
|
|
{
|
|
return (dmodel_t *)CopyArray(dmodels, nummodels, sizeof(*dmodels));
|
|
}
|
|
|
|
static uint8_t *BSP29_CopyVisData(const uint8_t *dvisdata, int visdatasize)
|
|
{
|
|
return (uint8_t *)CopyArray(dvisdata, visdatasize, 1);
|
|
}
|
|
|
|
static uint8_t *BSP29_CopyLightData(const uint8_t *dlightdata, int lightdatasize)
|
|
{
|
|
return (uint8_t *)CopyArray(dlightdata, lightdatasize, 1);
|
|
}
|
|
|
|
static dmiptexlump_t *BSP29_CopyTexData(const dmiptexlump_t *dtexdata, int texdatasize)
|
|
{
|
|
return (dmiptexlump_t *)CopyArray(dtexdata, texdatasize, 1);
|
|
}
|
|
|
|
static char *BSP29_CopyEntData(const char *dentdata, int entdatasize)
|
|
{
|
|
return (char *)CopyArray(dentdata, entdatasize, 1);
|
|
}
|
|
|
|
static dplane_t *BSP29_CopyPlanes(const dplane_t *dplanes, int numplanes)
|
|
{
|
|
return (dplane_t *)CopyArray(dplanes, numplanes, sizeof(*dplanes));
|
|
}
|
|
|
|
static dvertex_t *BSP29_CopyVertexes(const dvertex_t *dvertexes, int numvertexes)
|
|
{
|
|
return (dvertex_t *)CopyArray(dvertexes, numvertexes, sizeof(*dvertexes));
|
|
}
|
|
|
|
static texinfo_t *BSP29_CopyTexinfo(const texinfo_t *texinfo, int numtexinfo)
|
|
{
|
|
return (texinfo_t *)CopyArray(texinfo, numtexinfo, sizeof(*texinfo));
|
|
}
|
|
|
|
static int32_t *BSP29_CopySurfedges(const int32_t *surfedges, int numsurfedges)
|
|
{
|
|
return (int32_t *)CopyArray(surfedges, numsurfedges, sizeof(*surfedges));
|
|
}
|
|
|
|
static bsp2_dface_t *BSP2_CopyFaces(const bsp2_dface_t *dfaces, int numfaces)
|
|
{
|
|
return (bsp2_dface_t *)CopyArray(dfaces, numfaces, sizeof(*dfaces));
|
|
}
|
|
|
|
static bsp2_dclipnode_t *BSP2_CopyClipnodes(const bsp2_dclipnode_t *dclipnodes, int numclipnodes)
|
|
{
|
|
return (bsp2_dclipnode_t *)CopyArray(dclipnodes, numclipnodes, sizeof(*dclipnodes));
|
|
}
|
|
|
|
static bsp2_dedge_t *BSP2_CopyEdges(const bsp2_dedge_t *dedges, int numedges)
|
|
{
|
|
return (bsp2_dedge_t *)CopyArray(dedges, numedges, sizeof(*dedges));
|
|
}
|
|
|
|
static uint32_t *BSP2_CopyMarksurfaces(const uint32_t *marksurfaces, int nummarksurfaces)
|
|
{
|
|
return (uint32_t *)CopyArray(marksurfaces, nummarksurfaces, sizeof(*marksurfaces));
|
|
}
|
|
|
|
static bsp2_dnode_t *BSP2_CopyNodes(const bsp2_dnode_t *dnodes, int numnodes)
|
|
{
|
|
return (bsp2_dnode_t *)CopyArray(dnodes, numnodes, sizeof(*dnodes));
|
|
}
|
|
|
|
static uint32_t *Q2BSPtoM_CopyLeafBrushes(const uint16_t *leafbrushes, int count)
|
|
{
|
|
const uint16_t *leafbrush = leafbrushes;
|
|
uint32_t *newdata, *leafbrushes2;
|
|
int i;
|
|
|
|
newdata = leafbrushes2 = static_cast<uint32_t *>(malloc(count * sizeof(*leafbrushes2)));
|
|
|
|
for (i = 0; i < count; i++, leafbrush++, leafbrushes2++)
|
|
*leafbrushes2 = *leafbrush;
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static uint16_t *MBSPtoQ2_CopyLeafBrushes(const uint32_t *leafbrushes, int count)
|
|
{
|
|
const uint32_t *leafbrush = leafbrushes;
|
|
uint16_t *newdata, *leafbrushes2;
|
|
int i;
|
|
|
|
newdata = leafbrushes2 = static_cast<uint16_t *>(malloc(count * sizeof(*leafbrushes2)));
|
|
|
|
for (i = 0; i < count; i++, leafbrush++, leafbrushes2++)
|
|
*leafbrushes2 = *leafbrush;
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static uint32_t *Q2BSP_Qbism_CopyLeafBrushes(const uint32_t *leafbrushes, int count)
|
|
{
|
|
return (uint32_t *)CopyArray(leafbrushes, count, sizeof(*leafbrushes));
|
|
}
|
|
|
|
static darea_t *Q2BSP_CopyAreas(const darea_t *areas, int count)
|
|
{
|
|
return (darea_t *)CopyArray(areas, count, sizeof(*areas));
|
|
}
|
|
|
|
static dareaportal_t *Q2BSP_CopyAreaPortals(const dareaportal_t *areaportals, int count)
|
|
{
|
|
return (dareaportal_t *)CopyArray(areaportals, count, sizeof(*areaportals));
|
|
}
|
|
|
|
static dbrush_t *Q2BSP_CopyBrushes(const dbrush_t *brushes, int count)
|
|
{
|
|
return (dbrush_t *)CopyArray(brushes, count, sizeof(*brushes));
|
|
}
|
|
|
|
static q2_dbrushside_qbism_t *Q2BSPtoM_CopyBrushSides(const dbrushside_t *dbrushsides, int count)
|
|
{
|
|
const dbrushside_t *brushside = dbrushsides;
|
|
q2_dbrushside_qbism_t *newdata, *brushsides2;
|
|
int i;
|
|
|
|
newdata = brushsides2 = static_cast<q2_dbrushside_qbism_t *>(malloc(count * sizeof(*brushsides2)));
|
|
|
|
for (i = 0; i < count; i++, brushside++, brushsides2++) {
|
|
brushsides2->planenum = brushside->planenum;
|
|
brushsides2->texinfo = brushside->texinfo;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
static q2_dbrushside_qbism_t *Q2BSP_Qbism_CopyBrushSides(const q2_dbrushside_qbism_t *brushsides, int count)
|
|
{
|
|
return (q2_dbrushside_qbism_t *)CopyArray(brushsides, count, sizeof(*brushsides));
|
|
}
|
|
|
|
static dbrushside_t *MBSPtoQ2_CopyBrushSides(const q2_dbrushside_qbism_t *dbrushsides, int count)
|
|
{
|
|
const q2_dbrushside_qbism_t *brushside = dbrushsides;
|
|
dbrushside_t *newdata, *brushsides2;
|
|
int i;
|
|
|
|
newdata = brushsides2 = static_cast<dbrushside_t *>(malloc(count * sizeof(*brushsides2)));
|
|
|
|
for (i = 0; i < count; i++, brushside++, brushsides2++) {
|
|
brushsides2->planenum = brushside->planenum;
|
|
brushsides2->texinfo = brushside->texinfo;
|
|
}
|
|
|
|
return newdata;
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================================
|
|
* Freeing BSP structs
|
|
* =========================================================================
|
|
*/
|
|
|
|
static void FreeBSP29(bsp29_t *bsp)
|
|
{
|
|
free(bsp->dmodels);
|
|
free(bsp->dvisdata);
|
|
free(bsp->dlightdata);
|
|
free(bsp->dtexdata);
|
|
free(bsp->dentdata);
|
|
free(bsp->dleafs);
|
|
free(bsp->dplanes);
|
|
free(bsp->dvertexes);
|
|
free(bsp->dnodes);
|
|
free(bsp->texinfo);
|
|
free(bsp->dfaces);
|
|
free(bsp->dclipnodes);
|
|
free(bsp->dedges);
|
|
free(bsp->dmarksurfaces);
|
|
free(bsp->dsurfedges);
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
}
|
|
|
|
static void FreeBSP2RMQ(bsp2rmq_t *bsp)
|
|
{
|
|
free(bsp->dmodels);
|
|
free(bsp->dvisdata);
|
|
free(bsp->dlightdata);
|
|
free(bsp->dtexdata);
|
|
free(bsp->dentdata);
|
|
free(bsp->dleafs);
|
|
free(bsp->dplanes);
|
|
free(bsp->dvertexes);
|
|
free(bsp->dnodes);
|
|
free(bsp->texinfo);
|
|
free(bsp->dfaces);
|
|
free(bsp->dclipnodes);
|
|
free(bsp->dedges);
|
|
free(bsp->dmarksurfaces);
|
|
free(bsp->dsurfedges);
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
}
|
|
|
|
static void FreeBSP2(bsp2_t *bsp)
|
|
{
|
|
free(bsp->dmodels);
|
|
free(bsp->dvisdata);
|
|
free(bsp->dlightdata);
|
|
free(bsp->dtexdata);
|
|
free(bsp->dentdata);
|
|
free(bsp->dleafs);
|
|
free(bsp->dplanes);
|
|
free(bsp->dvertexes);
|
|
free(bsp->dnodes);
|
|
free(bsp->texinfo);
|
|
free(bsp->dfaces);
|
|
free(bsp->dclipnodes);
|
|
free(bsp->dedges);
|
|
free(bsp->dmarksurfaces);
|
|
free(bsp->dsurfedges);
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
}
|
|
|
|
static void FreeQ2BSP(q2bsp_t *bsp)
|
|
{
|
|
free(bsp->dmodels);
|
|
free(bsp->dvis);
|
|
free(bsp->dlightdata);
|
|
free(bsp->dentdata);
|
|
free(bsp->dleafs);
|
|
free(bsp->dplanes);
|
|
free(bsp->dvertexes);
|
|
free(bsp->dnodes);
|
|
free(bsp->texinfo);
|
|
free(bsp->dfaces);
|
|
free(bsp->dedges);
|
|
free(bsp->dleaffaces);
|
|
free(bsp->dleafbrushes);
|
|
free(bsp->dsurfedges);
|
|
free(bsp->dareas);
|
|
free(bsp->dareaportals);
|
|
free(bsp->dbrushes);
|
|
free(bsp->dbrushsides);
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
}
|
|
|
|
static void FreeQ2BSP_QBSP(q2bsp_qbism_t *bsp)
|
|
{
|
|
free(bsp->dmodels);
|
|
free(bsp->dvis);
|
|
free(bsp->dlightdata);
|
|
free(bsp->dentdata);
|
|
free(bsp->dleafs);
|
|
free(bsp->dplanes);
|
|
free(bsp->dvertexes);
|
|
free(bsp->dnodes);
|
|
free(bsp->texinfo);
|
|
free(bsp->dfaces);
|
|
free(bsp->dedges);
|
|
free(bsp->dleaffaces);
|
|
free(bsp->dleafbrushes);
|
|
free(bsp->dsurfedges);
|
|
free(bsp->dareas);
|
|
free(bsp->dareaportals);
|
|
free(bsp->dbrushes);
|
|
free(bsp->dbrushsides);
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
}
|
|
|
|
static void FreeMBSP(mbsp_t *bsp)
|
|
{
|
|
free(bsp->dmodels);
|
|
free(bsp->dvisdata);
|
|
free(bsp->dlightdata);
|
|
free(bsp->dtexdata);
|
|
free(bsp->drgbatexdata); //mxd
|
|
free(bsp->dentdata);
|
|
free(bsp->dleafs);
|
|
free(bsp->dplanes);
|
|
free(bsp->dvertexes);
|
|
free(bsp->dnodes);
|
|
free(bsp->texinfo);
|
|
free(bsp->dfaces);
|
|
free(bsp->dclipnodes);
|
|
free(bsp->dedges);
|
|
free(bsp->dleaffaces);
|
|
free(bsp->dleafbrushes);
|
|
free(bsp->dsurfedges);
|
|
free(bsp->dareas);
|
|
free(bsp->dareaportals);
|
|
free(bsp->dbrushes);
|
|
free(bsp->dbrushsides);
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
}
|
|
|
|
inline void
|
|
ConvertBSPToMFormatComplete(const bspversion_t **mbsp_loadversion, const bspversion_t *version, bspdata_t *bspdata)
|
|
{
|
|
*mbsp_loadversion = bspdata->version;
|
|
bspdata->version = version;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* ConvertBSPFormat
|
|
* - BSP is assumed to be in CPU byte order already
|
|
* - No checks are done here (yet) for overflow of values when down-converting
|
|
* =========================================================================
|
|
*/
|
|
void
|
|
ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
|
{
|
|
if (bspdata->version == to_version)
|
|
return;
|
|
|
|
// conversions to GENERIC_BSP
|
|
if (to_version == &bspver_generic) {
|
|
if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) {
|
|
const bsp29_t *bsp29 = &bspdata->data.bsp29;
|
|
mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(mbsp, 0, sizeof(*mbsp));
|
|
|
|
// copy counts
|
|
mbsp->nummodels = bsp29->nummodels;
|
|
mbsp->visdatasize = bsp29->visdatasize;
|
|
mbsp->lightdatasize = bsp29->lightdatasize;
|
|
mbsp->texdatasize = bsp29->texdatasize;
|
|
mbsp->entdatasize = bsp29->entdatasize;
|
|
mbsp->numleafs = bsp29->numleafs;
|
|
mbsp->numplanes = bsp29->numplanes;
|
|
mbsp->numvertexes = bsp29->numvertexes;
|
|
mbsp->numnodes = bsp29->numnodes;
|
|
mbsp->numtexinfo = bsp29->numtexinfo;
|
|
mbsp->numfaces = bsp29->numfaces;
|
|
mbsp->numclipnodes = bsp29->numclipnodes;
|
|
mbsp->numedges = bsp29->numedges;
|
|
mbsp->numleaffaces = bsp29->nummarksurfaces;
|
|
mbsp->numsurfedges = bsp29->numsurfedges;
|
|
|
|
// copy or convert data
|
|
mbsp->dmodels = BSP29_CopyModels(bsp29->dmodels, bsp29->nummodels);
|
|
mbsp->dvisdata = BSP29_CopyVisData(bsp29->dvisdata, bsp29->visdatasize);
|
|
mbsp->dlightdata = BSP29_CopyLightData(bsp29->dlightdata, bsp29->lightdatasize);
|
|
mbsp->dtexdata = BSP29_CopyTexData(bsp29->dtexdata, bsp29->texdatasize);
|
|
mbsp->dentdata = BSP29_CopyEntData(bsp29->dentdata, bsp29->entdatasize);
|
|
mbsp->dleafs = BSP29toM_Leafs(bsp29->dleafs, bsp29->numleafs);
|
|
mbsp->dplanes = BSP29_CopyPlanes(bsp29->dplanes, bsp29->numplanes);
|
|
mbsp->dvertexes = BSP29_CopyVertexes(bsp29->dvertexes, bsp29->numvertexes);
|
|
mbsp->dnodes = BSP29to2_Nodes(bsp29->dnodes, bsp29->numnodes);
|
|
mbsp->texinfo = BSP29toM_Texinfo(bsp29->texinfo, bsp29->numtexinfo);
|
|
mbsp->dfaces = BSP29to2_Faces(bsp29->dfaces, bsp29->numfaces);
|
|
mbsp->dclipnodes = BSP29to2_Clipnodes(bsp29->dclipnodes, bsp29->numclipnodes);
|
|
mbsp->dedges = BSP29to2_Edges(bsp29->dedges, bsp29->numedges);
|
|
mbsp->dleaffaces = BSP29to2_Marksurfaces(bsp29->dmarksurfaces, bsp29->nummarksurfaces);
|
|
mbsp->dsurfedges = BSP29_CopySurfedges(bsp29->dsurfedges, bsp29->numsurfedges);
|
|
|
|
/* Free old data */
|
|
FreeBSP29((bsp29_t *)bsp29);
|
|
|
|
/* Conversion complete! */
|
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
|
|
|
return;
|
|
}
|
|
|
|
else if (bspdata->version == &bspver_q2) {
|
|
const q2bsp_t *q2bsp = &bspdata->data.q2bsp;
|
|
mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(mbsp, 0, sizeof(*mbsp));
|
|
|
|
// copy counts
|
|
mbsp->nummodels = q2bsp->nummodels;
|
|
mbsp->visdatasize = q2bsp->visdatasize;
|
|
mbsp->lightdatasize = q2bsp->lightdatasize;
|
|
mbsp->entdatasize = q2bsp->entdatasize;
|
|
mbsp->numleafs = q2bsp->numleafs;
|
|
mbsp->numplanes = q2bsp->numplanes;
|
|
mbsp->numvertexes = q2bsp->numvertexes;
|
|
mbsp->numnodes = q2bsp->numnodes;
|
|
mbsp->numtexinfo = q2bsp->numtexinfo;
|
|
mbsp->numfaces = q2bsp->numfaces;
|
|
mbsp->numedges = q2bsp->numedges;
|
|
mbsp->numleaffaces = q2bsp->numleaffaces;
|
|
mbsp->numleafbrushes = q2bsp->numleafbrushes;
|
|
mbsp->numsurfedges = q2bsp->numsurfedges;
|
|
mbsp->numareas = q2bsp->numareas;
|
|
mbsp->numareaportals = q2bsp->numareaportals;
|
|
mbsp->numbrushes = q2bsp->numbrushes;
|
|
mbsp->numbrushsides = q2bsp->numbrushsides;
|
|
|
|
// copy or convert data
|
|
mbsp->dmodels = Q2BSPtoM_Models(q2bsp->dmodels, q2bsp->nummodels);
|
|
mbsp->dvisdata = (uint8_t *)CopyArray(q2bsp->dvis, q2bsp->visdatasize, 1);
|
|
mbsp->dlightdata = BSP29_CopyLightData(q2bsp->dlightdata, q2bsp->lightdatasize);
|
|
mbsp->dentdata = BSP29_CopyEntData(q2bsp->dentdata, q2bsp->entdatasize);
|
|
mbsp->dleafs = Q2BSPtoM_Leafs(q2bsp->dleafs, q2bsp->numleafs);
|
|
mbsp->dplanes = BSP29_CopyPlanes(q2bsp->dplanes, q2bsp->numplanes);
|
|
mbsp->dvertexes = BSP29_CopyVertexes(q2bsp->dvertexes, q2bsp->numvertexes);
|
|
mbsp->dnodes = Q2BSPto2_Nodes(q2bsp->dnodes, q2bsp->numnodes);
|
|
mbsp->texinfo = Q2BSPtoM_Texinfo(q2bsp->texinfo, q2bsp->numtexinfo);
|
|
mbsp->dfaces = Q2BSPto2_Faces(q2bsp->dfaces, q2bsp->numfaces);
|
|
mbsp->dedges = BSP29to2_Edges(q2bsp->dedges, q2bsp->numedges);
|
|
mbsp->dleaffaces = BSP29to2_Marksurfaces(q2bsp->dleaffaces, q2bsp->numleaffaces);
|
|
mbsp->dleafbrushes = Q2BSPtoM_CopyLeafBrushes(q2bsp->dleafbrushes, q2bsp->numleafbrushes);
|
|
mbsp->dsurfedges = BSP29_CopySurfedges(q2bsp->dsurfedges, q2bsp->numsurfedges);
|
|
|
|
mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas);
|
|
mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals);
|
|
|
|
mbsp->dbrushes = Q2BSP_CopyBrushes(q2bsp->dbrushes, q2bsp->numbrushes);
|
|
mbsp->dbrushsides = Q2BSPtoM_CopyBrushSides(q2bsp->dbrushsides, q2bsp->numbrushsides);
|
|
|
|
/* Free old data */
|
|
FreeQ2BSP((q2bsp_t *)q2bsp);
|
|
|
|
/* Conversion complete! */
|
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
|
|
|
return;
|
|
} else if (bspdata->version == &bspver_qbism) {
|
|
const q2bsp_qbism_t *q2bsp = &bspdata->data.q2bsp_qbism;
|
|
mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(mbsp, 0, sizeof(*mbsp));
|
|
|
|
// copy counts
|
|
mbsp->nummodels = q2bsp->nummodels;
|
|
mbsp->visdatasize = q2bsp->visdatasize;
|
|
mbsp->lightdatasize = q2bsp->lightdatasize;
|
|
mbsp->entdatasize = q2bsp->entdatasize;
|
|
mbsp->numleafs = q2bsp->numleafs;
|
|
mbsp->numplanes = q2bsp->numplanes;
|
|
mbsp->numvertexes = q2bsp->numvertexes;
|
|
mbsp->numnodes = q2bsp->numnodes;
|
|
mbsp->numtexinfo = q2bsp->numtexinfo;
|
|
mbsp->numfaces = q2bsp->numfaces;
|
|
mbsp->numedges = q2bsp->numedges;
|
|
mbsp->numleaffaces = q2bsp->numleaffaces;
|
|
mbsp->numleafbrushes = q2bsp->numleafbrushes;
|
|
mbsp->numsurfedges = q2bsp->numsurfedges;
|
|
mbsp->numareas = q2bsp->numareas;
|
|
mbsp->numareaportals = q2bsp->numareaportals;
|
|
mbsp->numbrushes = q2bsp->numbrushes;
|
|
mbsp->numbrushsides = q2bsp->numbrushsides;
|
|
|
|
// copy or convert data
|
|
mbsp->dmodels = Q2BSPtoM_Models(q2bsp->dmodels, q2bsp->nummodels);
|
|
mbsp->dvisdata = (uint8_t *)CopyArray(q2bsp->dvis, q2bsp->visdatasize, 1);
|
|
mbsp->dlightdata = BSP29_CopyLightData(q2bsp->dlightdata, q2bsp->lightdatasize);
|
|
mbsp->dentdata = BSP29_CopyEntData(q2bsp->dentdata, q2bsp->entdatasize);
|
|
mbsp->dleafs = Q2BSP_QBSPtoM_Leafs(q2bsp->dleafs, q2bsp->numleafs);
|
|
mbsp->dplanes = BSP29_CopyPlanes(q2bsp->dplanes, q2bsp->numplanes);
|
|
mbsp->dvertexes = BSP29_CopyVertexes(q2bsp->dvertexes, q2bsp->numvertexes);
|
|
mbsp->dnodes = BSP2_CopyNodes(q2bsp->dnodes, q2bsp->numnodes);
|
|
mbsp->texinfo = Q2BSPtoM_Texinfo(q2bsp->texinfo, q2bsp->numtexinfo);
|
|
mbsp->dfaces = Q2BSP_QBSPto2_Faces(q2bsp->dfaces, q2bsp->numfaces);
|
|
mbsp->dedges = BSP2_CopyEdges(q2bsp->dedges, q2bsp->numedges);
|
|
mbsp->dleaffaces = BSP2_CopyMarksurfaces(q2bsp->dleaffaces, q2bsp->numleaffaces);
|
|
mbsp->dleafbrushes = Q2BSP_Qbism_CopyLeafBrushes(q2bsp->dleafbrushes, q2bsp->numleafbrushes);
|
|
mbsp->dsurfedges = BSP29_CopySurfedges(q2bsp->dsurfedges, q2bsp->numsurfedges);
|
|
|
|
mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas);
|
|
mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals);
|
|
|
|
mbsp->dbrushes = Q2BSP_CopyBrushes(q2bsp->dbrushes, q2bsp->numbrushes);
|
|
mbsp->dbrushsides = Q2BSP_Qbism_CopyBrushSides(q2bsp->dbrushsides, q2bsp->numbrushsides);
|
|
|
|
/* Free old data */
|
|
FreeQ2BSP_QBSP((q2bsp_qbism_t *)q2bsp);
|
|
|
|
/* Conversion complete! */
|
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
|
|
|
return;
|
|
}
|
|
|
|
else if (bspdata->version == &bspver_bsp2rmq) {
|
|
const bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq;
|
|
mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(mbsp, 0, sizeof(*mbsp));
|
|
|
|
// copy counts
|
|
mbsp->nummodels = bsp2rmq->nummodels;
|
|
mbsp->visdatasize = bsp2rmq->visdatasize;
|
|
mbsp->lightdatasize = bsp2rmq->lightdatasize;
|
|
mbsp->texdatasize = bsp2rmq->texdatasize;
|
|
mbsp->entdatasize = bsp2rmq->entdatasize;
|
|
mbsp->numleafs = bsp2rmq->numleafs;
|
|
mbsp->numplanes = bsp2rmq->numplanes;
|
|
mbsp->numvertexes = bsp2rmq->numvertexes;
|
|
mbsp->numnodes = bsp2rmq->numnodes;
|
|
mbsp->numtexinfo = bsp2rmq->numtexinfo;
|
|
mbsp->numfaces = bsp2rmq->numfaces;
|
|
mbsp->numclipnodes = bsp2rmq->numclipnodes;
|
|
mbsp->numedges = bsp2rmq->numedges;
|
|
mbsp->numleaffaces = bsp2rmq->nummarksurfaces;
|
|
mbsp->numsurfedges = bsp2rmq->numsurfedges;
|
|
|
|
// copy or convert data
|
|
mbsp->dmodels = BSP29_CopyModels(bsp2rmq->dmodels, bsp2rmq->nummodels);
|
|
mbsp->dvisdata = BSP29_CopyVisData(bsp2rmq->dvisdata, bsp2rmq->visdatasize);
|
|
mbsp->dlightdata = BSP29_CopyLightData(bsp2rmq->dlightdata, bsp2rmq->lightdatasize);
|
|
mbsp->dtexdata = BSP29_CopyTexData(bsp2rmq->dtexdata, bsp2rmq->texdatasize);
|
|
mbsp->dentdata = BSP29_CopyEntData(bsp2rmq->dentdata, bsp2rmq->entdatasize);
|
|
mbsp->dleafs = BSP2rmqtoM_Leafs(bsp2rmq->dleafs, bsp2rmq->numleafs);
|
|
mbsp->dplanes = BSP29_CopyPlanes(bsp2rmq->dplanes, bsp2rmq->numplanes);
|
|
mbsp->dvertexes = BSP29_CopyVertexes(bsp2rmq->dvertexes, bsp2rmq->numvertexes);
|
|
mbsp->dnodes = BSP2rmqto2_Nodes(bsp2rmq->dnodes, bsp2rmq->numnodes);
|
|
mbsp->texinfo = BSP29toM_Texinfo(bsp2rmq->texinfo, bsp2rmq->numtexinfo);
|
|
mbsp->dfaces = BSP2_CopyFaces(bsp2rmq->dfaces, bsp2rmq->numfaces);
|
|
mbsp->dclipnodes = BSP2_CopyClipnodes(bsp2rmq->dclipnodes, bsp2rmq->numclipnodes);
|
|
mbsp->dedges = BSP2_CopyEdges(bsp2rmq->dedges, bsp2rmq->numedges);
|
|
mbsp->dleaffaces = BSP2_CopyMarksurfaces(bsp2rmq->dmarksurfaces, bsp2rmq->nummarksurfaces);
|
|
mbsp->dsurfedges = BSP29_CopySurfedges(bsp2rmq->dsurfedges, bsp2rmq->numsurfedges);
|
|
|
|
/* Free old data */
|
|
FreeBSP2RMQ((bsp2rmq_t *)bsp2rmq);
|
|
|
|
/* Conversion complete! */
|
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
|
|
|
return;
|
|
}
|
|
|
|
else if (bspdata->version == &bspver_bsp2) {
|
|
const bsp2_t *bsp2 = &bspdata->data.bsp2;
|
|
mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(mbsp, 0, sizeof(*mbsp));
|
|
|
|
// copy counts
|
|
mbsp->nummodels = bsp2->nummodels;
|
|
mbsp->visdatasize = bsp2->visdatasize;
|
|
mbsp->lightdatasize = bsp2->lightdatasize;
|
|
mbsp->texdatasize = bsp2->texdatasize;
|
|
mbsp->entdatasize = bsp2->entdatasize;
|
|
mbsp->numleafs = bsp2->numleafs;
|
|
mbsp->numplanes = bsp2->numplanes;
|
|
mbsp->numvertexes = bsp2->numvertexes;
|
|
mbsp->numnodes = bsp2->numnodes;
|
|
mbsp->numtexinfo = bsp2->numtexinfo;
|
|
mbsp->numfaces = bsp2->numfaces;
|
|
mbsp->numclipnodes = bsp2->numclipnodes;
|
|
mbsp->numedges = bsp2->numedges;
|
|
mbsp->numleaffaces = bsp2->nummarksurfaces;
|
|
mbsp->numsurfedges = bsp2->numsurfedges;
|
|
|
|
// copy or convert data
|
|
mbsp->dmodels = BSP29_CopyModels(bsp2->dmodels, bsp2->nummodels);
|
|
mbsp->dvisdata = BSP29_CopyVisData(bsp2->dvisdata, bsp2->visdatasize);
|
|
mbsp->dlightdata = BSP29_CopyLightData(bsp2->dlightdata, bsp2->lightdatasize);
|
|
mbsp->dtexdata = BSP29_CopyTexData(bsp2->dtexdata, bsp2->texdatasize);
|
|
mbsp->dentdata = BSP29_CopyEntData(bsp2->dentdata, bsp2->entdatasize);
|
|
mbsp->dleafs = BSP2toM_Leafs(bsp2->dleafs, bsp2->numleafs);
|
|
mbsp->dplanes = BSP29_CopyPlanes(bsp2->dplanes, bsp2->numplanes);
|
|
mbsp->dvertexes = BSP29_CopyVertexes(bsp2->dvertexes, bsp2->numvertexes);
|
|
mbsp->dnodes = BSP2_CopyNodes(bsp2->dnodes, bsp2->numnodes);
|
|
mbsp->texinfo = BSP29toM_Texinfo(bsp2->texinfo, bsp2->numtexinfo);
|
|
mbsp->dfaces = BSP2_CopyFaces(bsp2->dfaces, bsp2->numfaces);
|
|
mbsp->dclipnodes = BSP2_CopyClipnodes(bsp2->dclipnodes, bsp2->numclipnodes);
|
|
mbsp->dedges = BSP2_CopyEdges(bsp2->dedges, bsp2->numedges);
|
|
mbsp->dleaffaces = BSP2_CopyMarksurfaces(bsp2->dmarksurfaces, bsp2->nummarksurfaces);
|
|
mbsp->dsurfedges = BSP29_CopySurfedges(bsp2->dsurfedges, bsp2->numsurfedges);
|
|
|
|
/* Free old data */
|
|
FreeBSP2((bsp2_t *)bsp2);
|
|
|
|
/* Conversion complete! */
|
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
|
|
|
return;
|
|
}
|
|
}
|
|
// conversions from GENERIC_BSP
|
|
else if (bspdata->version == &bspver_generic) {
|
|
if (to_version == &bspver_q1 || to_version == &bspver_h2 || to_version == &bspver_hl) {
|
|
bsp29_t *bsp29 = &bspdata->data.bsp29;
|
|
const mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(bsp29, 0, sizeof(*bsp29));
|
|
|
|
// copy counts
|
|
bsp29->nummodels = mbsp->nummodels;
|
|
bsp29->visdatasize = mbsp->visdatasize;
|
|
bsp29->lightdatasize = mbsp->lightdatasize;
|
|
bsp29->texdatasize = mbsp->texdatasize;
|
|
bsp29->entdatasize = mbsp->entdatasize;
|
|
bsp29->numleafs = mbsp->numleafs;
|
|
bsp29->numplanes = mbsp->numplanes;
|
|
bsp29->numvertexes = mbsp->numvertexes;
|
|
bsp29->numnodes = mbsp->numnodes;
|
|
bsp29->numtexinfo = mbsp->numtexinfo;
|
|
bsp29->numfaces = mbsp->numfaces;
|
|
bsp29->numclipnodes = mbsp->numclipnodes;
|
|
bsp29->numedges = mbsp->numedges;
|
|
bsp29->nummarksurfaces = mbsp->numleaffaces;
|
|
bsp29->numsurfedges = mbsp->numsurfedges;
|
|
|
|
// copy or convert data
|
|
bsp29->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels);
|
|
bsp29->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize);
|
|
bsp29->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize);
|
|
bsp29->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize);
|
|
bsp29->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize);
|
|
bsp29->dleafs = MBSPto29_Leafs(mbsp->dleafs, mbsp->numleafs);
|
|
bsp29->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes);
|
|
bsp29->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes);
|
|
bsp29->dnodes = BSP2to29_Nodes(mbsp->dnodes, mbsp->numnodes);
|
|
bsp29->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo);
|
|
bsp29->dfaces = BSP2to29_Faces(mbsp->dfaces, mbsp->numfaces);
|
|
bsp29->dclipnodes = BSP2to29_Clipnodes(mbsp->dclipnodes, mbsp->numclipnodes);
|
|
bsp29->dedges = BSP2to29_Edges(mbsp->dedges, mbsp->numedges);
|
|
bsp29->dmarksurfaces = BSP2to29_Marksurfaces(mbsp->dleaffaces, mbsp->numleaffaces);
|
|
bsp29->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges);
|
|
|
|
/* Free old data */
|
|
FreeMBSP((mbsp_t *)mbsp);
|
|
|
|
/* Conversion complete! */
|
|
bspdata->version = to_version;
|
|
|
|
return;
|
|
}
|
|
|
|
else if (to_version == &bspver_q2) {
|
|
const mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
q2bsp_t *q2bsp = &bspdata->data.q2bsp;
|
|
|
|
memset(q2bsp, 0, sizeof(*q2bsp));
|
|
|
|
// copy counts
|
|
q2bsp->nummodels = mbsp->nummodels;
|
|
q2bsp->visdatasize = mbsp->visdatasize;
|
|
q2bsp->lightdatasize = mbsp->lightdatasize;
|
|
q2bsp->entdatasize = mbsp->entdatasize;
|
|
q2bsp->numleafs = mbsp->numleafs;
|
|
q2bsp->numplanes = mbsp->numplanes;
|
|
q2bsp->numvertexes = mbsp->numvertexes;
|
|
q2bsp->numnodes = mbsp->numnodes;
|
|
q2bsp->numtexinfo = mbsp->numtexinfo;
|
|
q2bsp->numfaces = mbsp->numfaces;
|
|
q2bsp->numedges = mbsp->numedges;
|
|
q2bsp->numleaffaces = mbsp->numleaffaces;
|
|
q2bsp->numleafbrushes = mbsp->numleafbrushes;
|
|
q2bsp->numsurfedges = mbsp->numsurfedges;
|
|
q2bsp->numareas = mbsp->numareas;
|
|
q2bsp->numareaportals = mbsp->numareaportals;
|
|
q2bsp->numbrushes = mbsp->numbrushes;
|
|
q2bsp->numbrushsides = mbsp->numbrushsides;
|
|
|
|
// copy or convert data
|
|
q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels);
|
|
q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1);
|
|
q2bsp->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize);
|
|
q2bsp->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize);
|
|
q2bsp->dleafs = MBSPtoQ2_Leafs(mbsp->dleafs, mbsp->numleafs);
|
|
q2bsp->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes);
|
|
q2bsp->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes);
|
|
q2bsp->dnodes = BSP2toQ2_Nodes(mbsp->dnodes, mbsp->numnodes);
|
|
q2bsp->texinfo = MBSPtoQ2_Texinfo(mbsp->texinfo, mbsp->numtexinfo);
|
|
q2bsp->dfaces = BSP2toQ2_Faces(mbsp->dfaces, mbsp->numfaces);
|
|
q2bsp->dedges = BSP2to29_Edges(mbsp->dedges, mbsp->numedges);
|
|
q2bsp->dleaffaces = BSP2to29_Marksurfaces(mbsp->dleaffaces, mbsp->numleaffaces);
|
|
q2bsp->dleafbrushes = MBSPtoQ2_CopyLeafBrushes(mbsp->dleafbrushes, mbsp->numleafbrushes);
|
|
q2bsp->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges);
|
|
|
|
q2bsp->dareas = Q2BSP_CopyAreas(mbsp->dareas, mbsp->numareas);
|
|
q2bsp->dareaportals = Q2BSP_CopyAreaPortals(mbsp->dareaportals, mbsp->numareaportals);
|
|
|
|
q2bsp->dbrushes = Q2BSP_CopyBrushes(mbsp->dbrushes, mbsp->numbrushes);
|
|
q2bsp->dbrushsides = MBSPtoQ2_CopyBrushSides(mbsp->dbrushsides, mbsp->numbrushsides);
|
|
|
|
/* Free old data */
|
|
FreeMBSP((mbsp_t *)mbsp);
|
|
|
|
/* Conversion complete! */
|
|
bspdata->version = to_version;
|
|
|
|
return;
|
|
} else if (to_version == &bspver_qbism) {
|
|
const mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
q2bsp_qbism_t *q2bsp = &bspdata->data.q2bsp_qbism;
|
|
|
|
memset(q2bsp, 0, sizeof(*q2bsp));
|
|
|
|
// copy counts
|
|
q2bsp->nummodels = mbsp->nummodels;
|
|
q2bsp->visdatasize = mbsp->visdatasize;
|
|
q2bsp->lightdatasize = mbsp->lightdatasize;
|
|
q2bsp->entdatasize = mbsp->entdatasize;
|
|
q2bsp->numleafs = mbsp->numleafs;
|
|
q2bsp->numplanes = mbsp->numplanes;
|
|
q2bsp->numvertexes = mbsp->numvertexes;
|
|
q2bsp->numnodes = mbsp->numnodes;
|
|
q2bsp->numtexinfo = mbsp->numtexinfo;
|
|
q2bsp->numfaces = mbsp->numfaces;
|
|
q2bsp->numedges = mbsp->numedges;
|
|
q2bsp->numleaffaces = mbsp->numleaffaces;
|
|
q2bsp->numleafbrushes = mbsp->numleafbrushes;
|
|
q2bsp->numsurfedges = mbsp->numsurfedges;
|
|
q2bsp->numareas = mbsp->numareas;
|
|
q2bsp->numareaportals = mbsp->numareaportals;
|
|
q2bsp->numbrushes = mbsp->numbrushes;
|
|
q2bsp->numbrushsides = mbsp->numbrushsides;
|
|
|
|
// copy or convert data
|
|
q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels);
|
|
q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1);
|
|
q2bsp->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize);
|
|
q2bsp->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize);
|
|
q2bsp->dleafs = MBSPtoQ2_Qbism_Leafs(mbsp->dleafs, mbsp->numleafs);
|
|
q2bsp->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes);
|
|
q2bsp->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes);
|
|
q2bsp->dnodes = BSP2_CopyNodes(mbsp->dnodes, mbsp->numnodes);
|
|
q2bsp->texinfo = MBSPtoQ2_Texinfo(mbsp->texinfo, mbsp->numtexinfo);
|
|
q2bsp->dfaces = BSP2toQ2_Qbism_Faces(mbsp->dfaces, mbsp->numfaces);
|
|
q2bsp->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges);
|
|
q2bsp->dleaffaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces);
|
|
q2bsp->dleafbrushes = Q2BSP_Qbism_CopyLeafBrushes(mbsp->dleafbrushes, mbsp->numleafbrushes);
|
|
q2bsp->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges);
|
|
|
|
q2bsp->dareas = Q2BSP_CopyAreas(mbsp->dareas, mbsp->numareas);
|
|
q2bsp->dareaportals = Q2BSP_CopyAreaPortals(mbsp->dareaportals, mbsp->numareaportals);
|
|
|
|
q2bsp->dbrushes = Q2BSP_CopyBrushes(mbsp->dbrushes, mbsp->numbrushes);
|
|
q2bsp->dbrushsides = Q2BSP_Qbism_CopyBrushSides(mbsp->dbrushsides, mbsp->numbrushsides);
|
|
|
|
/* Free old data */
|
|
FreeMBSP((mbsp_t *)mbsp);
|
|
|
|
/* Conversion complete! */
|
|
bspdata->version = to_version;
|
|
|
|
return;
|
|
}
|
|
|
|
else if (to_version == &bspver_bsp2rmq) {
|
|
bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq;
|
|
const mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(bsp2rmq, 0, sizeof(*bsp2rmq));
|
|
|
|
// copy counts
|
|
bsp2rmq->nummodels = mbsp->nummodels;
|
|
bsp2rmq->visdatasize = mbsp->visdatasize;
|
|
bsp2rmq->lightdatasize = mbsp->lightdatasize;
|
|
bsp2rmq->texdatasize = mbsp->texdatasize;
|
|
bsp2rmq->entdatasize = mbsp->entdatasize;
|
|
bsp2rmq->numleafs = mbsp->numleafs;
|
|
bsp2rmq->numplanes = mbsp->numplanes;
|
|
bsp2rmq->numvertexes = mbsp->numvertexes;
|
|
bsp2rmq->numnodes = mbsp->numnodes;
|
|
bsp2rmq->numtexinfo = mbsp->numtexinfo;
|
|
bsp2rmq->numfaces = mbsp->numfaces;
|
|
bsp2rmq->numclipnodes = mbsp->numclipnodes;
|
|
bsp2rmq->numedges = mbsp->numedges;
|
|
bsp2rmq->nummarksurfaces = mbsp->numleaffaces;
|
|
bsp2rmq->numsurfedges = mbsp->numsurfedges;
|
|
|
|
// copy or convert data
|
|
bsp2rmq->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels);
|
|
bsp2rmq->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize);
|
|
bsp2rmq->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize);
|
|
bsp2rmq->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize);
|
|
bsp2rmq->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize);
|
|
bsp2rmq->dleafs = MBSPto2rmq_Leafs(mbsp->dleafs, mbsp->numleafs);
|
|
bsp2rmq->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes);
|
|
bsp2rmq->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes);
|
|
bsp2rmq->dnodes = BSP2to2rmq_Nodes(mbsp->dnodes, mbsp->numnodes);
|
|
bsp2rmq->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo);
|
|
bsp2rmq->dfaces = BSP2_CopyFaces(mbsp->dfaces, mbsp->numfaces);
|
|
bsp2rmq->dclipnodes = BSP2_CopyClipnodes(mbsp->dclipnodes, mbsp->numclipnodes);
|
|
bsp2rmq->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges);
|
|
bsp2rmq->dmarksurfaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces);
|
|
bsp2rmq->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges);
|
|
|
|
/* Free old data */
|
|
FreeMBSP((mbsp_t *)mbsp);
|
|
|
|
/* Conversion complete! */
|
|
bspdata->version = to_version;
|
|
|
|
return;
|
|
}
|
|
|
|
else if (to_version == &bspver_bsp2) {
|
|
bsp2_t *bsp2 = &bspdata->data.bsp2;
|
|
const mbsp_t *mbsp = &bspdata->data.mbsp;
|
|
|
|
memset(bsp2, 0, sizeof(*bsp2));
|
|
|
|
// copy counts
|
|
bsp2->nummodels = mbsp->nummodels;
|
|
bsp2->visdatasize = mbsp->visdatasize;
|
|
bsp2->lightdatasize = mbsp->lightdatasize;
|
|
bsp2->texdatasize = mbsp->texdatasize;
|
|
bsp2->entdatasize = mbsp->entdatasize;
|
|
bsp2->numleafs = mbsp->numleafs;
|
|
bsp2->numplanes = mbsp->numplanes;
|
|
bsp2->numvertexes = mbsp->numvertexes;
|
|
bsp2->numnodes = mbsp->numnodes;
|
|
bsp2->numtexinfo = mbsp->numtexinfo;
|
|
bsp2->numfaces = mbsp->numfaces;
|
|
bsp2->numclipnodes = mbsp->numclipnodes;
|
|
bsp2->numedges = mbsp->numedges;
|
|
bsp2->nummarksurfaces = mbsp->numleaffaces;
|
|
bsp2->numsurfedges = mbsp->numsurfedges;
|
|
|
|
// copy or convert data
|
|
bsp2->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels);
|
|
bsp2->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize);
|
|
bsp2->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize);
|
|
bsp2->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize);
|
|
bsp2->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize);
|
|
bsp2->dleafs = MBSPto2_Leafs(mbsp->dleafs, mbsp->numleafs);
|
|
bsp2->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes);
|
|
bsp2->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes);
|
|
bsp2->dnodes = BSP2_CopyNodes(mbsp->dnodes, mbsp->numnodes);
|
|
bsp2->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo);
|
|
bsp2->dfaces = BSP2_CopyFaces(mbsp->dfaces, mbsp->numfaces);
|
|
bsp2->dclipnodes = BSP2_CopyClipnodes(mbsp->dclipnodes, mbsp->numclipnodes);
|
|
bsp2->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges);
|
|
bsp2->dmarksurfaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces);
|
|
bsp2->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges);
|
|
|
|
/* Free old data */
|
|
FreeMBSP((mbsp_t *)mbsp);
|
|
|
|
/* Conversion complete! */
|
|
bspdata->version = to_version;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
Error("Don't know how to convert BSP version %s to %s",
|
|
BSPVersionString(bspdata->version), BSPVersionString(to_version));
|
|
}
|
|
|
|
static int
|
|
isHexen2(const dheader_t *header)
|
|
{
|
|
/*
|
|
the world should always have some face.
|
|
however, if the sizes are wrong then we're actually reading headnode[6]. hexen2 only used 5 hulls, so this should be 0 in hexen2, and not in quake.
|
|
*/
|
|
const dmodelq1_t *modelsq1 = (const dmodelq1_t*)((const uint8_t *)header + header->lumps[LUMP_MODELS].fileofs);
|
|
return !modelsq1->numfaces;
|
|
}
|
|
|
|
/*
|
|
* =========================================================================
|
|
* ...
|
|
* =========================================================================
|
|
*/
|
|
|
|
const lumpspec_t lumpspec_bsp29[] = {
|
|
{ "entities", sizeof(char) },
|
|
{ "planes", sizeof(dplane_t) },
|
|
{ "texture", sizeof(uint8_t) },
|
|
{ "vertexes", sizeof(dvertex_t) },
|
|
{ "visibility", sizeof(uint8_t) },
|
|
{ "nodes", sizeof(bsp29_dnode_t) },
|
|
{ "texinfos", sizeof(texinfo_t) },
|
|
{ "faces", sizeof(bsp29_dface_t) },
|
|
{ "lighting", sizeof(uint8_t) },
|
|
{ "clipnodes", sizeof(bsp29_dclipnode_t) },
|
|
{ "leafs", sizeof(bsp29_dleaf_t) },
|
|
{ "marksurfaces", sizeof(uint16_t) },
|
|
{ "edges", sizeof(bsp29_dedge_t) },
|
|
{ "surfedges", sizeof(int32_t) },
|
|
{ "models", sizeof(dmodel_t) },
|
|
};
|
|
|
|
const lumpspec_t lumpspec_bsp2rmq[] = {
|
|
{ "entities", sizeof(char) },
|
|
{ "planes", sizeof(dplane_t) },
|
|
{ "texture", sizeof(uint8_t) },
|
|
{ "vertexes", sizeof(dvertex_t) },
|
|
{ "visibility", sizeof(uint8_t) },
|
|
{ "nodes", sizeof(bsp2rmq_dnode_t) },
|
|
{ "texinfos", sizeof(texinfo_t) },
|
|
{ "faces", sizeof(bsp2_dface_t) },
|
|
{ "lighting", sizeof(uint8_t) },
|
|
{ "clipnodes", sizeof(bsp2_dclipnode_t ) },
|
|
{ "leafs", sizeof(bsp2rmq_dleaf_t) },
|
|
{ "marksurfaces", sizeof(uint32_t) },
|
|
{ "edges", sizeof(bsp2_dedge_t) },
|
|
{ "surfedges", sizeof(int32_t) },
|
|
{ "models", sizeof(dmodel_t) },
|
|
};
|
|
|
|
const lumpspec_t lumpspec_bsp2[] = {
|
|
{ "entities", sizeof(char) },
|
|
{ "planes", sizeof(dplane_t) },
|
|
{ "texture", sizeof(uint8_t) },
|
|
{ "vertexes", sizeof(dvertex_t) },
|
|
{ "visibility", sizeof(uint8_t) },
|
|
{ "nodes", sizeof(bsp2_dnode_t) },
|
|
{ "texinfos", sizeof(texinfo_t) },
|
|
{ "faces", sizeof(bsp2_dface_t) },
|
|
{ "lighting", sizeof(uint8_t) },
|
|
{ "clipnodes", sizeof(bsp2_dclipnode_t ) },
|
|
{ "leafs", sizeof(bsp2_dleaf_t) },
|
|
{ "marksurfaces", sizeof(uint32_t) },
|
|
{ "edges", sizeof(bsp2_dedge_t) },
|
|
{ "surfedges", sizeof(int32_t) },
|
|
{ "models", sizeof(dmodel_t) },
|
|
};
|
|
|
|
const lumpspec_t lumpspec_q2bsp[] = {
|
|
{ "entities", sizeof(char) },
|
|
{ "planes", sizeof(dplane_t) },
|
|
{ "vertexes", sizeof(dvertex_t) },
|
|
{ "visibility", sizeof(uint8_t) },
|
|
{ "nodes", sizeof(q2_dnode_t) },
|
|
{ "texinfos", sizeof(q2_texinfo_t) },
|
|
{ "faces", sizeof(q2_dface_t) },
|
|
{ "lighting", sizeof(uint8_t) },
|
|
{ "leafs", sizeof(q2_dleaf_t) },
|
|
{ "leaffaces", sizeof(uint16_t) },
|
|
{ "leafbrushes", sizeof(uint16_t) },
|
|
{ "edges", sizeof(bsp29_dedge_t) },
|
|
{ "surfedges", sizeof(int32_t) },
|
|
{ "models", sizeof(q2_dmodel_t) },
|
|
{ "brushes", sizeof(dbrush_t) },
|
|
{ "brushsides", sizeof(dbrushside_t) },
|
|
{ "pop", sizeof(uint8_t) },
|
|
{ "areas", sizeof(darea_t) },
|
|
{ "areaportals", sizeof(dareaportal_t) },
|
|
};
|
|
|
|
const lumpspec_t lumpspec_qbism[] = {
|
|
{ "entities", sizeof(char) },
|
|
{ "planes", sizeof(dplane_t) },
|
|
{ "vertexes", sizeof(dvertex_t) },
|
|
{ "visibility", sizeof(uint8_t) },
|
|
{ "nodes", sizeof(q2_dnode_qbism_t) },
|
|
{ "texinfos", sizeof(q2_texinfo_t) },
|
|
{ "faces", sizeof(q2_dface_qbism_t) },
|
|
{ "lighting", sizeof(uint8_t) },
|
|
{ "leafs", sizeof(q2_dleaf_qbism_t) },
|
|
{ "leaffaces", sizeof(uint32_t) },
|
|
{ "leafbrushes", sizeof(uint32_t) },
|
|
{ "edges", sizeof(q2_dedge_qbism_t) },
|
|
{ "surfedges", sizeof(int32_t) },
|
|
{ "models", sizeof(q2_dmodel_t) },
|
|
{ "brushes", sizeof(dbrush_t) },
|
|
{ "brushsides", sizeof(q2_dbrushside_qbism_t) },
|
|
{ "pop", sizeof(uint8_t) },
|
|
{ "areas", sizeof(darea_t) },
|
|
{ "areaportals", sizeof(dareaportal_t) },
|
|
};
|
|
|
|
static int
|
|
CopyLump(const void *header, const bspversion_t *version, const lump_t *lumps, int lumpnum, void *destptr)
|
|
{
|
|
const lumpspec_t *lumpspec;
|
|
uint8_t **bufferptr = static_cast<uint8_t **>(destptr);
|
|
uint8_t *buffer = *bufferptr;
|
|
int length;
|
|
int ofs;
|
|
|
|
if (version == &bspver_q1 || version == &bspver_h2 || version == &bspver_hl) {
|
|
lumpspec = &lumpspec_bsp29[lumpnum];
|
|
} else if (version == &bspver_bsp2rmq) {
|
|
lumpspec = &lumpspec_bsp2rmq[lumpnum];
|
|
} else if (version == &bspver_bsp2) {
|
|
lumpspec = &lumpspec_bsp2[lumpnum];
|
|
} else if (version == &bspver_q2) {
|
|
lumpspec = &lumpspec_q2bsp[lumpnum];
|
|
} else if (version == &bspver_qbism) {
|
|
lumpspec = &lumpspec_qbism[lumpnum];
|
|
} else {
|
|
Error("Unsupported BSP version: %s", BSPVersionString(version));
|
|
throw; //mxd. Fixes "Uninitialized variable" warning
|
|
}
|
|
|
|
length = lumps[lumpnum].filelen;
|
|
ofs = lumps[lumpnum].fileofs;
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
|
|
// convert non-Hexen II BSP model hulls over to Hexen II ones
|
|
if (lumpnum == LUMP_MODELS && (version == &bspver_q1 || version == &bspver_hl))
|
|
{ /*convert in-place. no need to care about endian here.*/
|
|
const dmodelq1_t *in = (const dmodelq1_t*)((const uint8_t *)header + ofs);
|
|
dmodel_t *out;
|
|
int i, j;
|
|
if (length % sizeof(dmodelq1_t))
|
|
Error("%s: odd %s lump size", __func__, lumpspec->name);
|
|
length /= sizeof(dmodelq1_t);
|
|
|
|
buffer = *bufferptr = static_cast<uint8_t *>(malloc(length * sizeof(dmodel_t)));
|
|
if (!buffer)
|
|
Error("%s: allocation of %i bytes failed.", __func__, length);
|
|
out = (dmodel_t*)buffer;
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
out[i].mins[j] = in[i].mins[j];
|
|
out[i].maxs[j] = in[i].maxs[j];
|
|
out[i].origin[j] = in[i].origin[j];
|
|
}
|
|
for (j = 0; j < MAX_MAP_HULLS_Q1; j++)
|
|
out[i].headnode[j] = in[i].headnode[j];
|
|
for ( ; j < MAX_MAP_HULLS_H2; j++)
|
|
out[i].headnode[j] = 0;
|
|
out[i].visleafs = in[i].visleafs;
|
|
out[i].firstface = in[i].firstface;
|
|
out[i].numfaces = in[i].numfaces;
|
|
}
|
|
return length;
|
|
}
|
|
else
|
|
{
|
|
if (length % lumpspec->size)
|
|
Error("%s: odd %s lump size", __func__, lumpspec->name);
|
|
|
|
buffer = *bufferptr = static_cast<uint8_t *>(malloc(length + 1));
|
|
if (!buffer)
|
|
Error("%s: allocation of %i bytes failed.", __func__, length);
|
|
|
|
memcpy(buffer, (const uint8_t *)header + ofs, length);
|
|
buffer[length] = 0; /* In case of corrupt entity lump */
|
|
|
|
return length / lumpspec->size;
|
|
}
|
|
}
|
|
|
|
void BSPX_AddLump(bspdata_t *bspdata, const char *xname, const void *xdata, size_t xsize)
|
|
{
|
|
bspxentry_t *e;
|
|
bspxentry_t **link;
|
|
if (!xdata)
|
|
{
|
|
for (link = &bspdata->bspxentries; *link; )
|
|
{
|
|
e = *link;
|
|
if (!strcmp(e->lumpname, xname))
|
|
{
|
|
*link = e->next;
|
|
free(e);
|
|
break;
|
|
}
|
|
else
|
|
link = &(*link)->next;
|
|
}
|
|
return;
|
|
}
|
|
for (e = bspdata->bspxentries; e; e = e->next)
|
|
{
|
|
if (!strcmp(e->lumpname, xname))
|
|
break;
|
|
}
|
|
if (!e)
|
|
{
|
|
e = static_cast<bspxentry_t *>(malloc(sizeof(*e)));
|
|
memset(e, 0, sizeof(*e));
|
|
strncpy(e->lumpname, xname, sizeof(e->lumpname));
|
|
e->next = bspdata->bspxentries;
|
|
bspdata->bspxentries = e;
|
|
}
|
|
|
|
//ericw -- make a copy
|
|
uint8_t *xdata_copy = (uint8_t*) malloc(xsize);
|
|
memcpy(xdata_copy, xdata, xsize);
|
|
|
|
e->lumpdata = xdata_copy;
|
|
e->lumpsize = xsize;
|
|
}
|
|
const void *BSPX_GetLump(bspdata_t *bspdata, const char *xname, size_t *xsize)
|
|
{
|
|
bspxentry_t *e;
|
|
for (e = bspdata->bspxentries; e; e = e->next)
|
|
{
|
|
if (!strcmp(e->lumpname, xname))
|
|
break;
|
|
}
|
|
if (e)
|
|
{
|
|
if (xsize)
|
|
*xsize = e->lumpsize;
|
|
return e->lumpdata;
|
|
}
|
|
else
|
|
{
|
|
if (xsize)
|
|
*xsize = 0;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* =============
|
|
* LoadBSPFile
|
|
* =============
|
|
*/
|
|
void
|
|
LoadBSPFile(char *filename, bspdata_t *bspdata)
|
|
{
|
|
int i;
|
|
uint32_t bspxofs;
|
|
const bspx_header_t *bspx;
|
|
|
|
bspdata->bspxentries = NULL;
|
|
|
|
logprint("LoadBSPFile: '%s'\n", filename);
|
|
|
|
/* load the file header */
|
|
uint8_t *file_data;
|
|
uint32_t flen = LoadFilePak(filename, &file_data);
|
|
|
|
/* transfer the header data to these variables */
|
|
int numlumps;
|
|
lump_t *lumps;
|
|
|
|
/* check for IBSP */
|
|
bspversion_t temp_version { LittleLong(((int *)file_data)[0]) };
|
|
|
|
if (temp_version.ident == Q2_BSPIDENT ||
|
|
temp_version.ident == Q2_QBISMIDENT) {
|
|
q2_dheader_t *q2header = (q2_dheader_t *)file_data;
|
|
q2header->version = LittleLong(q2header->version);
|
|
|
|
numlumps = Q2_HEADER_LUMPS;
|
|
temp_version.version = q2header->version;
|
|
lumps = q2header->lumps;
|
|
} else {
|
|
dheader_t *q1header = (dheader_t *)file_data;
|
|
q1header->version = LittleLong(q1header->version);
|
|
|
|
numlumps = BSP_LUMPS;
|
|
lumps = q1header->lumps;
|
|
|
|
// not useful for Q1BSP, but we'll initialize it to -1
|
|
temp_version.version = NO_VERSION;
|
|
}
|
|
|
|
/* check the file version */
|
|
if (!BSPVersionSupported(temp_version.ident, temp_version.version, &bspdata->version)) {
|
|
logprint("BSP is version %s\n", BSPVersionString(&temp_version));
|
|
Error("Sorry, this bsp version is not supported.");
|
|
} else {
|
|
logprint("BSP is version %s\n", BSPVersionString(bspdata->version));
|
|
}
|
|
|
|
/* swap the lump headers */
|
|
for (i = 0; i < numlumps; i++) {
|
|
lumps[i].fileofs = LittleLong(lumps[i].fileofs);
|
|
lumps[i].filelen = LittleLong(lumps[i].filelen);
|
|
}
|
|
|
|
/* copy the data */
|
|
if (bspdata->version == &bspver_q2) {
|
|
q2_dheader_t *header = (q2_dheader_t *)file_data;
|
|
q2bsp_t *bsp = &bspdata->data.q2bsp;
|
|
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
|
|
bsp->nummodels = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_MODELS, &bsp->dmodels);
|
|
bsp->numvertexes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VERTEXES, &bsp->dvertexes);
|
|
bsp->numplanes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_PLANES, &bsp->dplanes);
|
|
bsp->numleafs = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFS, &bsp->dleafs);
|
|
bsp->numnodes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_NODES, &bsp->dnodes);
|
|
bsp->numtexinfo = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_TEXINFO, &bsp->texinfo);
|
|
bsp->numfaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_FACES, &bsp->dfaces);
|
|
bsp->numleaffaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFFACES, &bsp->dleaffaces);
|
|
bsp->numleafbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFBRUSHES, &bsp->dleafbrushes);
|
|
bsp->numsurfedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_SURFEDGES, &bsp->dsurfedges);
|
|
bsp->numedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_EDGES, &bsp->dedges);
|
|
bsp->numbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHES, &bsp->dbrushes);
|
|
bsp->numbrushsides = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHSIDES, &bsp->dbrushsides);
|
|
bsp->numareas = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAS, &bsp->dareas);
|
|
bsp->numareaportals = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAPORTALS, &bsp->dareaportals);
|
|
|
|
bsp->visdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VISIBILITY, &bsp->dvis);
|
|
bsp->lightdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LIGHTING, &bsp->dlightdata);
|
|
bsp->entdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_ENTITIES, &bsp->dentdata);
|
|
|
|
CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_POP, &bsp->dpop);
|
|
} else if (bspdata->version == &bspver_qbism) {
|
|
q2_dheader_t *header = (q2_dheader_t *)file_data;
|
|
q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism;
|
|
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
|
|
bsp->nummodels = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_MODELS, &bsp->dmodels);
|
|
bsp->numvertexes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VERTEXES, &bsp->dvertexes);
|
|
bsp->numplanes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_PLANES, &bsp->dplanes);
|
|
bsp->numleafs = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFS, &bsp->dleafs);
|
|
bsp->numnodes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_NODES, &bsp->dnodes);
|
|
bsp->numtexinfo = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_TEXINFO, &bsp->texinfo);
|
|
bsp->numfaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_FACES, &bsp->dfaces);
|
|
bsp->numleaffaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFFACES, &bsp->dleaffaces);
|
|
bsp->numleafbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFBRUSHES, &bsp->dleafbrushes);
|
|
bsp->numsurfedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_SURFEDGES, &bsp->dsurfedges);
|
|
bsp->numedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_EDGES, &bsp->dedges);
|
|
bsp->numbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHES, &bsp->dbrushes);
|
|
bsp->numbrushsides = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHSIDES, &bsp->dbrushsides);
|
|
bsp->numareas = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAS, &bsp->dareas);
|
|
bsp->numareaportals = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAPORTALS, &bsp->dareaportals);
|
|
|
|
bsp->visdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VISIBILITY, &bsp->dvis);
|
|
bsp->lightdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LIGHTING, &bsp->dlightdata);
|
|
bsp->entdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_ENTITIES, &bsp->dentdata);
|
|
|
|
CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_POP, &bsp->dpop);
|
|
} else {
|
|
// Only Q1-like maps need hullcount
|
|
if (isHexen2((dheader_t *)file_data)) {
|
|
logprint("BSP appears to be from hexen2\n");
|
|
// swap version over to H2
|
|
bspdata->version = &bspver_h2;
|
|
bspdata->hullcount = MAX_MAP_HULLS_H2;
|
|
} else {
|
|
bspdata->hullcount = MAX_MAP_HULLS_Q1;
|
|
}
|
|
}
|
|
|
|
if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) {
|
|
dheader_t *header = (dheader_t *)file_data;
|
|
bsp29_t *bsp = &bspdata->data.bsp29;
|
|
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
|
|
bsp->nummodels = CopyLump(header, bspdata->version, header->lumps, LUMP_MODELS, &bsp->dmodels);
|
|
bsp->numvertexes = CopyLump(header, bspdata->version, header->lumps, LUMP_VERTEXES, &bsp->dvertexes);
|
|
bsp->numplanes = CopyLump(header, bspdata->version, header->lumps, LUMP_PLANES, &bsp->dplanes);
|
|
bsp->numleafs = CopyLump(header, bspdata->version, header->lumps, LUMP_LEAFS, &bsp->dleafs);
|
|
bsp->numnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_NODES, &bsp->dnodes);
|
|
bsp->numtexinfo = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXINFO, &bsp->texinfo);
|
|
bsp->numclipnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_CLIPNODES, &bsp->dclipnodes);
|
|
bsp->numfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_FACES, &bsp->dfaces);
|
|
bsp->nummarksurfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_MARKSURFACES, &bsp->dmarksurfaces);
|
|
bsp->numsurfedges = CopyLump(header, bspdata->version, header->lumps, LUMP_SURFEDGES, &bsp->dsurfedges);
|
|
bsp->numedges = CopyLump(header, bspdata->version, header->lumps, LUMP_EDGES, &bsp->dedges);
|
|
|
|
bsp->texdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXTURES, &bsp->dtexdata);
|
|
bsp->visdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_VISIBILITY, &bsp->dvisdata);
|
|
bsp->lightdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_LIGHTING, &bsp->dlightdata);
|
|
bsp->entdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_ENTITIES, &bsp->dentdata);
|
|
} else if (bspdata->version == &bspver_bsp2rmq) {
|
|
dheader_t *header = (dheader_t *)file_data;
|
|
bsp2rmq_t *bsp = &bspdata->data.bsp2rmq;
|
|
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
|
|
bsp->nummodels = CopyLump(header, bspdata->version, header->lumps, LUMP_MODELS, &bsp->dmodels);
|
|
bsp->numvertexes = CopyLump(header, bspdata->version, header->lumps, LUMP_VERTEXES, &bsp->dvertexes);
|
|
bsp->numplanes = CopyLump(header, bspdata->version, header->lumps, LUMP_PLANES, &bsp->dplanes);
|
|
bsp->numleafs = CopyLump(header, bspdata->version, header->lumps, LUMP_LEAFS, &bsp->dleafs);
|
|
bsp->numnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_NODES, &bsp->dnodes);
|
|
bsp->numtexinfo = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXINFO, &bsp->texinfo);
|
|
bsp->numclipnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_CLIPNODES, &bsp->dclipnodes);
|
|
bsp->numfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_FACES, &bsp->dfaces);
|
|
bsp->nummarksurfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_MARKSURFACES, &bsp->dmarksurfaces);
|
|
bsp->numsurfedges = CopyLump(header, bspdata->version, header->lumps, LUMP_SURFEDGES, &bsp->dsurfedges);
|
|
bsp->numedges = CopyLump(header, bspdata->version, header->lumps, LUMP_EDGES, &bsp->dedges);
|
|
|
|
bsp->texdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXTURES, &bsp->dtexdata);
|
|
bsp->visdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_VISIBILITY, &bsp->dvisdata);
|
|
bsp->lightdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_LIGHTING, &bsp->dlightdata);
|
|
bsp->entdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_ENTITIES, &bsp->dentdata);
|
|
} else if (bspdata->version == &bspver_bsp2) {
|
|
dheader_t *header = (dheader_t *)file_data;
|
|
bsp2_t *bsp = &bspdata->data.bsp2;
|
|
|
|
memset(bsp, 0, sizeof(*bsp));
|
|
|
|
bsp->nummodels = CopyLump(header, bspdata->version, header->lumps, LUMP_MODELS, &bsp->dmodels);
|
|
bsp->numvertexes = CopyLump(header, bspdata->version, header->lumps, LUMP_VERTEXES, &bsp->dvertexes);
|
|
bsp->numplanes = CopyLump(header, bspdata->version, header->lumps, LUMP_PLANES, &bsp->dplanes);
|
|
bsp->numleafs = CopyLump(header, bspdata->version, header->lumps, LUMP_LEAFS, &bsp->dleafs);
|
|
bsp->numnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_NODES, &bsp->dnodes);
|
|
bsp->numtexinfo = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXINFO, &bsp->texinfo);
|
|
bsp->numclipnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_CLIPNODES, &bsp->dclipnodes);
|
|
bsp->numfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_FACES, &bsp->dfaces);
|
|
bsp->nummarksurfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_MARKSURFACES, &bsp->dmarksurfaces);
|
|
bsp->numsurfedges = CopyLump(header, bspdata->version, header->lumps, LUMP_SURFEDGES, &bsp->dsurfedges);
|
|
bsp->numedges = CopyLump(header, bspdata->version, header->lumps, LUMP_EDGES, &bsp->dedges);
|
|
|
|
bsp->texdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXTURES, &bsp->dtexdata);
|
|
bsp->visdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_VISIBILITY, &bsp->dvisdata);
|
|
bsp->lightdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_LIGHTING, &bsp->dlightdata);
|
|
bsp->entdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_ENTITIES, &bsp->dentdata);
|
|
}
|
|
|
|
// detect BSPX
|
|
dheader_t *header = (dheader_t *)file_data;
|
|
|
|
/*bspx header is positioned exactly+4align at the end of the last lump position (regardless of order)*/
|
|
for (i = 0, bspxofs = 0; i < BSP_LUMPS; i++)
|
|
{
|
|
if (bspxofs < header->lumps[i].fileofs + header->lumps[i].filelen)
|
|
bspxofs = header->lumps[i].fileofs + header->lumps[i].filelen;
|
|
}
|
|
bspxofs = (bspxofs+3) & ~3;
|
|
/*okay, so that's where it *should* be if it exists */
|
|
if (bspxofs + sizeof(*bspx) <= flen)
|
|
{
|
|
int xlumps;
|
|
const bspx_lump_t *xlump;
|
|
bspx = (const bspx_header_t*)((const uint8_t*)header + bspxofs);
|
|
xlump = (const bspx_lump_t*)(bspx+1);
|
|
xlumps = LittleLong(bspx->numlumps);
|
|
if (!memcmp(&bspx->id,"BSPX",4) && xlumps >= 0 && bspxofs+sizeof(*bspx)+sizeof(*xlump)*xlumps <= flen)
|
|
{
|
|
/*header seems valid so far. just add the lumps as we normally would if we were generating them, ensuring that they get written out anew*/
|
|
while(xlumps --> 0)
|
|
{
|
|
uint32_t ofs = LittleLong(xlump[xlumps].fileofs);
|
|
uint32_t len = LittleLong(xlump[xlumps].filelen);
|
|
void *lumpdata = malloc(len);
|
|
memcpy(lumpdata, (const uint8_t*)header + ofs, len);
|
|
BSPX_AddLump(bspdata, xlump[xlumps].lumpname, lumpdata, len);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!memcmp(&bspx->id,"BSPX",4))
|
|
printf("invalid bspx header\n");
|
|
}
|
|
}
|
|
|
|
/* everything has been copied out */
|
|
free(file_data);
|
|
|
|
/* swap everything */
|
|
SwapBSPFile(bspdata, TO_CPU);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
typedef struct {
|
|
const bspversion_t *version;
|
|
|
|
// which one is used depends on version
|
|
union {
|
|
dheader_t q1header;
|
|
q2_dheader_t q2header;
|
|
};
|
|
|
|
FILE *file;
|
|
} bspfile_t;
|
|
|
|
static void
|
|
AddLump(bspfile_t *bspfile, int lumpnum, const void *data, int count)
|
|
{
|
|
bool q2 = false;
|
|
size_t size;
|
|
const lumpspec_t *lumpspec;
|
|
lump_t *lumps;
|
|
|
|
if (bspfile->version == &bspver_q1 || bspfile->version == &bspver_h2 || bspfile->version == &bspver_hl) {
|
|
lumpspec = &lumpspec_bsp29[lumpnum];
|
|
lumps = bspfile->q1header.lumps;
|
|
} else if (bspfile->version == &bspver_bsp2rmq) {
|
|
lumpspec = &lumpspec_bsp2rmq[lumpnum];
|
|
lumps = bspfile->q1header.lumps;
|
|
} else if (bspfile->version == &bspver_bsp2) {
|
|
lumpspec = &lumpspec_bsp2[lumpnum];
|
|
lumps = bspfile->q1header.lumps;
|
|
} else if (bspfile->version == &bspver_q2) {
|
|
lumpspec = &lumpspec_q2bsp[lumpnum];
|
|
lumps = bspfile->q2header.lumps;
|
|
} else if (bspfile->version == &bspver_qbism) {
|
|
lumpspec = &lumpspec_qbism[lumpnum];
|
|
lumps = bspfile->q2header.lumps;
|
|
} else {
|
|
Error("Unsupported BSP version: %s", BSPVersionString(bspfile->version));
|
|
throw; //mxd. Fixes "Uninitialized variable" warning
|
|
}
|
|
|
|
size = lumpspec->size * count;
|
|
|
|
uint8_t pad[4] = {0};
|
|
lump_t *lump = &lumps[lumpnum];
|
|
|
|
lump->fileofs = LittleLong(ftell(bspfile->file));
|
|
lump->filelen = LittleLong(size);
|
|
SafeWrite(bspfile->file, data, size);
|
|
if (size % 4)
|
|
SafeWrite(bspfile->file, pad, 4 - (size % 4));
|
|
}
|
|
|
|
static void
|
|
AddModelsLump(bspfile_t *bspfile, bspdata_t *bspdata, const void *data, int count)
|
|
{
|
|
if (bspdata->hullcount == MAX_MAP_HULLS_Q1)
|
|
{ /*convert in-place. no need to care about endian here.*/
|
|
lump_t *lump = &bspfile->q1header.lumps[LUMP_MODELS];
|
|
const dmodel_t *in = static_cast<const dmodel_t *>(data);
|
|
dmodelq1_t *out = static_cast<dmodelq1_t *>(malloc(count * sizeof(dmodelq1_t)));
|
|
int i, j;
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
out[i].mins[j] = in[i].mins[j];
|
|
out[i].maxs[j] = in[i].maxs[j];
|
|
out[i].origin[j] = in[i].origin[j];
|
|
}
|
|
for (j = 0; j < MAX_MAP_HULLS_Q1; j++)
|
|
out[i].headnode[j] = in[i].headnode[j];
|
|
out[i].visleafs = in[i].visleafs;
|
|
out[i].firstface = in[i].firstface;
|
|
out[i].numfaces = in[i].numfaces;
|
|
}
|
|
lump->fileofs = LittleLong(ftell(bspfile->file));
|
|
lump->filelen = LittleLong(sizeof(dmodelq1_t) * count);
|
|
SafeWrite(bspfile->file, out, lump->filelen);
|
|
free(out);
|
|
return;
|
|
}
|
|
else
|
|
AddLump(bspfile, LUMP_MODELS, data, count);
|
|
}
|
|
|
|
/*
|
|
* =============
|
|
* WriteBSPFile
|
|
* Swaps the bsp file in place, so it should not be referenced again
|
|
* =============
|
|
*/
|
|
void
|
|
WriteBSPFile(const char *filename, bspdata_t *bspdata)
|
|
{
|
|
bspfile_t bspfile;
|
|
memset(&bspfile, 0, sizeof(bspfile));
|
|
|
|
SwapBSPFile(bspdata, TO_DISK);
|
|
|
|
bspfile.version = bspdata->version;
|
|
|
|
// headers are union'd, so this sets both
|
|
bspfile.q2header.ident = LittleLong(bspfile.version->ident);
|
|
|
|
if (bspfile.version->version != NO_VERSION) {
|
|
bspfile.q2header.version = LittleLong(bspfile.version->version);
|
|
}
|
|
|
|
logprint("Writing %s as BSP version %s\n", filename, BSPVersionString(bspdata->version));
|
|
bspfile.file = SafeOpenWrite(filename);
|
|
|
|
/* Save header space, updated after adding the lumps */
|
|
if (bspfile.version->version != NO_VERSION) {
|
|
SafeWrite(bspfile.file, &bspfile.q2header, sizeof(bspfile.q2header));
|
|
} else {
|
|
SafeWrite(bspfile.file, &bspfile.q1header, sizeof(bspfile.q1header));
|
|
}
|
|
|
|
if (bspdata->version == &bspver_q1 ||
|
|
bspdata->version == &bspver_h2 ||
|
|
bspdata->version == &bspver_hl) {
|
|
bsp29_t *bsp = &bspdata->data.bsp29;
|
|
|
|
AddLump(&bspfile, LUMP_PLANES, bsp->dplanes, bsp->numplanes);
|
|
AddLump(&bspfile, LUMP_LEAFS, bsp->dleafs, bsp->numleafs);
|
|
AddLump(&bspfile, LUMP_VERTEXES, bsp->dvertexes, bsp->numvertexes);
|
|
AddLump(&bspfile, LUMP_NODES, bsp->dnodes, bsp->numnodes);
|
|
AddLump(&bspfile, LUMP_TEXINFO, bsp->texinfo, bsp->numtexinfo);
|
|
AddLump(&bspfile, LUMP_FACES, bsp->dfaces, bsp->numfaces);
|
|
AddLump(&bspfile, LUMP_CLIPNODES, bsp->dclipnodes, bsp->numclipnodes);
|
|
AddLump(&bspfile, LUMP_MARKSURFACES, bsp->dmarksurfaces, bsp->nummarksurfaces);
|
|
AddLump(&bspfile, LUMP_SURFEDGES, bsp->dsurfedges, bsp->numsurfedges);
|
|
AddLump(&bspfile, LUMP_EDGES, bsp->dedges, bsp->numedges);
|
|
AddModelsLump(&bspfile, bspdata, bsp->dmodels, bsp->nummodels);
|
|
|
|
AddLump(&bspfile, LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize);
|
|
AddLump(&bspfile, LUMP_VISIBILITY, bsp->dvisdata, bsp->visdatasize);
|
|
AddLump(&bspfile, LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize);
|
|
AddLump(&bspfile, LUMP_TEXTURES, bsp->dtexdata, bsp->texdatasize);
|
|
} else if (bspdata->version == &bspver_bsp2rmq) {
|
|
bsp2rmq_t *bsp = &bspdata->data.bsp2rmq;
|
|
|
|
AddLump(&bspfile, LUMP_PLANES, bsp->dplanes, bsp->numplanes);
|
|
AddLump(&bspfile, LUMP_LEAFS, bsp->dleafs, bsp->numleafs);
|
|
AddLump(&bspfile, LUMP_VERTEXES, bsp->dvertexes, bsp->numvertexes);
|
|
AddLump(&bspfile, LUMP_NODES, bsp->dnodes, bsp->numnodes);
|
|
AddLump(&bspfile, LUMP_TEXINFO, bsp->texinfo, bsp->numtexinfo);
|
|
AddLump(&bspfile, LUMP_FACES, bsp->dfaces, bsp->numfaces);
|
|
AddLump(&bspfile, LUMP_CLIPNODES, bsp->dclipnodes, bsp->numclipnodes);
|
|
AddLump(&bspfile, LUMP_MARKSURFACES, bsp->dmarksurfaces, bsp->nummarksurfaces);
|
|
AddLump(&bspfile, LUMP_SURFEDGES, bsp->dsurfedges, bsp->numsurfedges);
|
|
AddLump(&bspfile, LUMP_EDGES, bsp->dedges, bsp->numedges);
|
|
AddModelsLump(&bspfile, bspdata, bsp->dmodels, bsp->nummodels);
|
|
|
|
AddLump(&bspfile, LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize);
|
|
AddLump(&bspfile, LUMP_VISIBILITY, bsp->dvisdata, bsp->visdatasize);
|
|
AddLump(&bspfile, LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize);
|
|
AddLump(&bspfile, LUMP_TEXTURES, bsp->dtexdata, bsp->texdatasize);
|
|
} else if (bspdata->version == &bspver_bsp2) {
|
|
bsp2_t *bsp = &bspdata->data.bsp2;
|
|
|
|
AddLump(&bspfile, LUMP_PLANES, bsp->dplanes, bsp->numplanes);
|
|
AddLump(&bspfile, LUMP_LEAFS, bsp->dleafs, bsp->numleafs);
|
|
AddLump(&bspfile, LUMP_VERTEXES, bsp->dvertexes, bsp->numvertexes);
|
|
AddLump(&bspfile, LUMP_NODES, bsp->dnodes, bsp->numnodes);
|
|
AddLump(&bspfile, LUMP_TEXINFO, bsp->texinfo, bsp->numtexinfo);
|
|
AddLump(&bspfile, LUMP_FACES, bsp->dfaces, bsp->numfaces);
|
|
AddLump(&bspfile, LUMP_CLIPNODES, bsp->dclipnodes, bsp->numclipnodes);
|
|
AddLump(&bspfile, LUMP_MARKSURFACES, bsp->dmarksurfaces, bsp->nummarksurfaces);
|
|
AddLump(&bspfile, LUMP_SURFEDGES, bsp->dsurfedges, bsp->numsurfedges);
|
|
AddLump(&bspfile, LUMP_EDGES, bsp->dedges, bsp->numedges);
|
|
AddModelsLump(&bspfile, bspdata, bsp->dmodels, bsp->nummodels);
|
|
|
|
AddLump(&bspfile, LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize);
|
|
AddLump(&bspfile, LUMP_VISIBILITY, bsp->dvisdata, bsp->visdatasize);
|
|
AddLump(&bspfile, LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize);
|
|
AddLump(&bspfile, LUMP_TEXTURES, bsp->dtexdata, bsp->texdatasize);
|
|
} else if (bspdata->version == &bspver_q2) {
|
|
q2bsp_t *bsp = &bspdata->data.q2bsp;
|
|
|
|
AddLump(&bspfile, Q2_LUMP_MODELS, bsp->dmodels, bsp->nummodels);
|
|
AddLump(&bspfile, Q2_LUMP_VERTEXES, bsp->dvertexes, bsp->numvertexes);
|
|
AddLump(&bspfile, Q2_LUMP_PLANES, bsp->dplanes, bsp->numplanes);
|
|
AddLump(&bspfile, Q2_LUMP_LEAFS, bsp->dleafs, bsp->numleafs);
|
|
AddLump(&bspfile, Q2_LUMP_NODES, bsp->dnodes, bsp->numnodes);
|
|
AddLump(&bspfile, Q2_LUMP_TEXINFO, bsp->texinfo, bsp->numtexinfo);
|
|
AddLump(&bspfile, Q2_LUMP_FACES, bsp->dfaces, bsp->numfaces);
|
|
AddLump(&bspfile, Q2_LUMP_LEAFFACES, bsp->dleaffaces, bsp->numleaffaces);
|
|
AddLump(&bspfile, Q2_LUMP_LEAFBRUSHES, bsp->dleafbrushes, bsp->numleafbrushes);
|
|
AddLump(&bspfile, Q2_LUMP_SURFEDGES, bsp->dsurfedges, bsp->numsurfedges);
|
|
AddLump(&bspfile, Q2_LUMP_EDGES, bsp->dedges, bsp->numedges);
|
|
AddLump(&bspfile, Q2_LUMP_BRUSHES, bsp->dbrushes, bsp->numbrushes);
|
|
AddLump(&bspfile, Q2_LUMP_BRUSHSIDES, bsp->dbrushsides, bsp->numbrushsides);
|
|
AddLump(&bspfile, Q2_LUMP_AREAS, bsp->dareas, bsp->numareas);
|
|
AddLump(&bspfile, Q2_LUMP_AREAPORTALS, bsp->dareaportals, bsp->numareaportals);
|
|
|
|
AddLump(&bspfile, Q2_LUMP_VISIBILITY, bsp->dvis, bsp->visdatasize);
|
|
AddLump(&bspfile, Q2_LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize);
|
|
AddLump(&bspfile, Q2_LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize);
|
|
AddLump(&bspfile, Q2_LUMP_POP, bsp->dpop, sizeof(bsp->dpop));
|
|
} else if (bspdata->version == &bspver_qbism) {
|
|
q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism;
|
|
|
|
AddLump(&bspfile, Q2_LUMP_MODELS, bsp->dmodels, bsp->nummodels);
|
|
AddLump(&bspfile, Q2_LUMP_VERTEXES, bsp->dvertexes, bsp->numvertexes);
|
|
AddLump(&bspfile, Q2_LUMP_PLANES, bsp->dplanes, bsp->numplanes);
|
|
AddLump(&bspfile, Q2_LUMP_LEAFS, bsp->dleafs, bsp->numleafs);
|
|
AddLump(&bspfile, Q2_LUMP_NODES, bsp->dnodes, bsp->numnodes);
|
|
AddLump(&bspfile, Q2_LUMP_TEXINFO, bsp->texinfo, bsp->numtexinfo);
|
|
AddLump(&bspfile, Q2_LUMP_FACES, bsp->dfaces, bsp->numfaces);
|
|
AddLump(&bspfile, Q2_LUMP_LEAFFACES, bsp->dleaffaces, bsp->numleaffaces);
|
|
AddLump(&bspfile, Q2_LUMP_LEAFBRUSHES, bsp->dleafbrushes, bsp->numleafbrushes);
|
|
AddLump(&bspfile, Q2_LUMP_SURFEDGES, bsp->dsurfedges, bsp->numsurfedges);
|
|
AddLump(&bspfile, Q2_LUMP_EDGES, bsp->dedges, bsp->numedges);
|
|
AddLump(&bspfile, Q2_LUMP_BRUSHES, bsp->dbrushes, bsp->numbrushes);
|
|
AddLump(&bspfile, Q2_LUMP_BRUSHSIDES, bsp->dbrushsides, bsp->numbrushsides);
|
|
AddLump(&bspfile, Q2_LUMP_AREAS, bsp->dareas, bsp->numareas);
|
|
AddLump(&bspfile, Q2_LUMP_AREAPORTALS, bsp->dareaportals, bsp->numareaportals);
|
|
|
|
AddLump(&bspfile, Q2_LUMP_VISIBILITY, bsp->dvis, bsp->visdatasize);
|
|
AddLump(&bspfile, Q2_LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize);
|
|
AddLump(&bspfile, Q2_LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize);
|
|
AddLump(&bspfile, Q2_LUMP_POP, bsp->dpop, sizeof(bsp->dpop));
|
|
} else {
|
|
Error("Unknown format");
|
|
}
|
|
|
|
/*BSPX lumps are at a 4-byte alignment after the last of any official lump*/
|
|
if (bspdata->bspxentries)
|
|
{
|
|
bspx_header_t xheader;
|
|
bspxentry_t *x;
|
|
bspx_lump_t xlumps[64];
|
|
uint32_t l;
|
|
uint32_t bspxheader = ftell(bspfile.file);
|
|
if (bspxheader & 3)
|
|
Error("BSPX header is misaligned");
|
|
xheader.id[0] = 'B';
|
|
xheader.id[1] = 'S';
|
|
xheader.id[2] = 'P';
|
|
xheader.id[3] = 'X';
|
|
xheader.numlumps = 0;
|
|
for (x = bspdata->bspxentries; x; x = x->next)
|
|
xheader.numlumps++;
|
|
|
|
if (xheader.numlumps > sizeof(xlumps)/sizeof(xlumps[0])) /*eep*/
|
|
xheader.numlumps = sizeof(xlumps)/sizeof(xlumps[0]);
|
|
|
|
SafeWrite(bspfile.file, &xheader, sizeof(xheader));
|
|
SafeWrite(bspfile.file, xlumps, xheader.numlumps * sizeof(xlumps[0]));
|
|
|
|
for (x = bspdata->bspxentries, l = 0; x && l < xheader.numlumps; x = x->next, l++)
|
|
{
|
|
uint8_t pad[4] = {0};
|
|
xlumps[l].filelen = LittleLong(x->lumpsize);
|
|
xlumps[l].fileofs = LittleLong(ftell(bspfile.file));
|
|
strncpy(xlumps[l].lumpname, x->lumpname, sizeof(xlumps[l].lumpname));
|
|
SafeWrite(bspfile.file, x->lumpdata, x->lumpsize);
|
|
if (x->lumpsize % 4)
|
|
SafeWrite(bspfile.file, pad, 4 - (x->lumpsize % 4));
|
|
}
|
|
|
|
fseek(bspfile.file, bspxheader, SEEK_SET);
|
|
SafeWrite(bspfile.file, &xheader, sizeof(xheader));
|
|
SafeWrite(bspfile.file, xlumps, xheader.numlumps * sizeof(xlumps[0]));
|
|
}
|
|
|
|
fseek(bspfile.file, 0, SEEK_SET);
|
|
|
|
// write the real header
|
|
if (bspfile.version->version != NO_VERSION) {
|
|
SafeWrite(bspfile.file, &bspfile.q2header, sizeof(bspfile.q2header));
|
|
} else {
|
|
SafeWrite(bspfile.file, &bspfile.q1header, sizeof(bspfile.q1header));
|
|
}
|
|
|
|
fclose(bspfile.file);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
static void
|
|
PrintLumpSize(const lumpspec_t *lumpspec, int lumptype, int count)
|
|
{
|
|
const lumpspec_t *lump = &lumpspec[lumptype];
|
|
logprint("%7i %-12s %10i\n", count, lump->name, count * (int)lump->size);
|
|
}
|
|
|
|
/*
|
|
* =============
|
|
* PrintBSPFileSizes
|
|
* Dumps info about the bsp data
|
|
* =============
|
|
*/
|
|
void
|
|
PrintBSPFileSizes(const bspdata_t *bspdata)
|
|
{
|
|
int numtextures = 0;
|
|
|
|
if (bspdata->version == &bspver_q2) {
|
|
const q2bsp_t *bsp = &bspdata->data.q2bsp;
|
|
const lumpspec_t *lumpspec = lumpspec_q2bsp;
|
|
|
|
logprint("%7i %-12s\n", bsp->nummodels, "models");
|
|
|
|
PrintLumpSize(lumpspec, Q2_LUMP_PLANES, bsp->numplanes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_VERTEXES, bsp->numvertexes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_NODES, bsp->numnodes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_TEXINFO, bsp->numtexinfo);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_FACES, bsp->numfaces);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_LEAFS, bsp->numleafs);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_LEAFFACES, bsp->numleaffaces);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_LEAFBRUSHES, bsp->numleafbrushes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_EDGES, bsp->numedges);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_SURFEDGES, bsp->numsurfedges);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_BRUSHES, bsp->numbrushes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_BRUSHSIDES, bsp->numbrushsides);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_AREAS, bsp->numareas);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_AREAPORTALS, bsp->numareaportals);
|
|
|
|
logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize);
|
|
} else if (bspdata->version == &bspver_qbism) {
|
|
const q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism;
|
|
const lumpspec_t *lumpspec = lumpspec_qbism;
|
|
|
|
logprint("%7i %-12s\n", bsp->nummodels, "models");
|
|
|
|
PrintLumpSize(lumpspec, Q2_LUMP_PLANES, bsp->numplanes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_VERTEXES, bsp->numvertexes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_NODES, bsp->numnodes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_TEXINFO, bsp->numtexinfo);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_FACES, bsp->numfaces);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_LEAFS, bsp->numleafs);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_LEAFFACES, bsp->numleaffaces);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_LEAFBRUSHES, bsp->numleafbrushes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_EDGES, bsp->numedges);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_SURFEDGES, bsp->numsurfedges);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_BRUSHES, bsp->numbrushes);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_BRUSHSIDES, bsp->numbrushsides);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_AREAS, bsp->numareas);
|
|
PrintLumpSize(lumpspec, Q2_LUMP_AREAPORTALS, bsp->numareaportals);
|
|
|
|
logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize);
|
|
} else if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) {
|
|
const bsp29_t *bsp = &bspdata->data.bsp29;
|
|
const lumpspec_t *lumpspec = lumpspec_bsp29;
|
|
|
|
if (bsp->texdatasize)
|
|
numtextures = bsp->dtexdata->nummiptex;
|
|
|
|
logprint("%7i %-12s\n", bsp->nummodels, "models");
|
|
|
|
PrintLumpSize(lumpspec, LUMP_PLANES, bsp->numplanes);
|
|
PrintLumpSize(lumpspec, LUMP_VERTEXES, bsp->numvertexes);
|
|
PrintLumpSize(lumpspec, LUMP_NODES, bsp->numnodes);
|
|
PrintLumpSize(lumpspec, LUMP_TEXINFO, bsp->numtexinfo);
|
|
PrintLumpSize(lumpspec, LUMP_FACES, bsp->numfaces);
|
|
PrintLumpSize(lumpspec, LUMP_CLIPNODES, bsp->numclipnodes);
|
|
PrintLumpSize(lumpspec, LUMP_LEAFS, bsp->numleafs);
|
|
PrintLumpSize(lumpspec, LUMP_MARKSURFACES, bsp->nummarksurfaces);
|
|
PrintLumpSize(lumpspec, LUMP_EDGES, bsp->numedges);
|
|
PrintLumpSize(lumpspec, LUMP_SURFEDGES, bsp->numsurfedges);
|
|
|
|
logprint("%7i %-12s %10i\n", numtextures, "textures", bsp->texdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize);
|
|
|
|
if (bspdata->bspxentries)
|
|
{
|
|
bspxentry_t *x;
|
|
for (x = bspdata->bspxentries; x; x = x->next) {
|
|
logprint("%7s %-12s %10i\n", "BSPX", x->lumpname, (int)x->lumpsize);
|
|
}
|
|
}
|
|
} else if (bspdata->version == &bspver_bsp2rmq) {
|
|
const bsp2rmq_t *bsp = &bspdata->data.bsp2rmq;
|
|
const lumpspec_t *lumpspec = lumpspec_bsp2rmq;
|
|
|
|
if (bsp->texdatasize)
|
|
numtextures = bsp->dtexdata->nummiptex;
|
|
|
|
logprint("%7i %-12s\n", bsp->nummodels, "models");
|
|
|
|
PrintLumpSize(lumpspec, LUMP_PLANES, bsp->numplanes);
|
|
PrintLumpSize(lumpspec, LUMP_VERTEXES, bsp->numvertexes);
|
|
PrintLumpSize(lumpspec, LUMP_NODES, bsp->numnodes);
|
|
PrintLumpSize(lumpspec, LUMP_TEXINFO, bsp->numtexinfo);
|
|
PrintLumpSize(lumpspec, LUMP_FACES, bsp->numfaces);
|
|
PrintLumpSize(lumpspec, LUMP_CLIPNODES, bsp->numclipnodes);
|
|
PrintLumpSize(lumpspec, LUMP_LEAFS, bsp->numleafs);
|
|
PrintLumpSize(lumpspec, LUMP_MARKSURFACES, bsp->nummarksurfaces);
|
|
PrintLumpSize(lumpspec, LUMP_EDGES, bsp->numedges);
|
|
PrintLumpSize(lumpspec, LUMP_SURFEDGES, bsp->numsurfedges);
|
|
|
|
logprint("%7i %-12s %10i\n", numtextures, "textures", bsp->texdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize);
|
|
} else if (bspdata->version == &bspver_bsp2) {
|
|
const bsp2_t *bsp = &bspdata->data.bsp2;
|
|
const lumpspec_t *lumpspec = lumpspec_bsp2;
|
|
|
|
if (bsp->texdatasize)
|
|
numtextures = bsp->dtexdata->nummiptex;
|
|
|
|
logprint("%7i %-12s\n", bsp->nummodels, "models");
|
|
|
|
PrintLumpSize(lumpspec, LUMP_PLANES, bsp->numplanes);
|
|
PrintLumpSize(lumpspec, LUMP_VERTEXES, bsp->numvertexes);
|
|
PrintLumpSize(lumpspec, LUMP_NODES, bsp->numnodes);
|
|
PrintLumpSize(lumpspec, LUMP_TEXINFO, bsp->numtexinfo);
|
|
PrintLumpSize(lumpspec, LUMP_FACES, bsp->numfaces);
|
|
PrintLumpSize(lumpspec, LUMP_CLIPNODES, bsp->numclipnodes);
|
|
PrintLumpSize(lumpspec, LUMP_LEAFS, bsp->numleafs);
|
|
PrintLumpSize(lumpspec, LUMP_MARKSURFACES, bsp->nummarksurfaces);
|
|
PrintLumpSize(lumpspec, LUMP_EDGES, bsp->numedges);
|
|
PrintLumpSize(lumpspec, LUMP_SURFEDGES, bsp->numsurfedges);
|
|
|
|
logprint("%7i %-12s %10i\n", numtextures, "textures", bsp->texdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize);
|
|
logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize);
|
|
}
|
|
}
|