Merge branch 'qbsp-use-common' of https://github.com/ericwa/ericw-tools into qbsp-use-common
# Conflicts: # common/bspfile.cc # qbsp/writebsp.cc
This commit is contained in:
commit
01d1400971
|
|
@ -20,6 +20,7 @@
|
||||||
#include <common/cmdlib.hh>
|
#include <common/cmdlib.hh>
|
||||||
#include <common/mathlib.hh>
|
#include <common/mathlib.hh>
|
||||||
#include <common/bspfile.hh>
|
#include <common/bspfile.hh>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
bool q1_surf_is_lightmapped(const surfflags_t &flags) {
|
bool q1_surf_is_lightmapped(const surfflags_t &flags) {
|
||||||
return !(flags.native & TEX_SPECIAL);
|
return !(flags.native & TEX_SPECIAL);
|
||||||
|
|
@ -972,6 +973,60 @@ BSP29toM_Leafs(const bsp29_dleaf_t *dleafs29, int numleafs) {
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
OverflowsInt16(float input) {
|
||||||
|
constexpr float minvalue = static_cast<float>(INT16_MIN);
|
||||||
|
constexpr float maxvalue = static_cast<float>(INT16_MAX);
|
||||||
|
|
||||||
|
if (input < minvalue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (input > maxvalue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
OverflowsInt16(int32_t input) {
|
||||||
|
if (input < INT16_MIN) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (input > INT16_MAX) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
OverflowsUint16(uint32_t input) {
|
||||||
|
if (input > INT16_MAX) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
MBSPto29_Leafs_Validate(const mleaf_t *mleafs, int numleafs) {
|
||||||
|
const mleaf_t *mleaf = mleafs;
|
||||||
|
|
||||||
|
for (int i = 0; i < numleafs; i++, mleaf++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
const float min_j = floor(mleaf->mins[j]);
|
||||||
|
const float max_j = ceil(mleaf->maxs[j]);
|
||||||
|
|
||||||
|
if (OverflowsInt16(min_j) || OverflowsInt16(max_j)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (OverflowsUint16(mleaf->firstmarksurface)
|
||||||
|
|| OverflowsUint16(mleaf->nummarksurfaces)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bsp29_dleaf_t *
|
static bsp29_dleaf_t *
|
||||||
MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) {
|
MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) {
|
||||||
const mleaf_t *mleaf = mleafs;
|
const mleaf_t *mleaf = mleafs;
|
||||||
|
|
@ -984,8 +1039,8 @@ MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) {
|
||||||
dleaf29->contents = mleaf->contents;
|
dleaf29->contents = mleaf->contents;
|
||||||
dleaf29->visofs = mleaf->visofs;
|
dleaf29->visofs = mleaf->visofs;
|
||||||
for (j = 0; j < 3; j++) {
|
for (j = 0; j < 3; j++) {
|
||||||
dleaf29->mins[j] = mleaf->mins[j];
|
dleaf29->mins[j] = floor(mleaf->mins[j]);
|
||||||
dleaf29->maxs[j] = mleaf->maxs[j];
|
dleaf29->maxs[j] = ceil(mleaf->maxs[j]);
|
||||||
}
|
}
|
||||||
dleaf29->firstmarksurface = mleaf->firstmarksurface;
|
dleaf29->firstmarksurface = mleaf->firstmarksurface;
|
||||||
dleaf29->nummarksurfaces = mleaf->nummarksurfaces;
|
dleaf29->nummarksurfaces = mleaf->nummarksurfaces;
|
||||||
|
|
@ -1662,6 +1717,31 @@ BSP29to2_Nodes(const bsp29_dnode_t *dnodes29, int numnodes) {
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
BSP2to29_Nodes_Validate(const bsp2_dnode_t *dnodes2, int numnodes) {
|
||||||
|
const bsp2_dnode_t *dnode2 = dnodes2;
|
||||||
|
|
||||||
|
for (int i = 0; i < numnodes; i++, dnode2++) {
|
||||||
|
if (OverflowsInt16(dnode2->children[0]) || OverflowsInt16(dnode2->children[1])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
const float min_j = floor(dnode2->mins[j]);
|
||||||
|
const float max_j = ceil(dnode2->maxs[j]);
|
||||||
|
|
||||||
|
if (OverflowsInt16(min_j) || OverflowsInt16(max_j)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (OverflowsUint16(dnode2->firstface)
|
||||||
|
|| OverflowsUint16(dnode2->numfaces)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bsp29_dnode_t *
|
static bsp29_dnode_t *
|
||||||
BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
|
BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
|
||||||
const bsp2_dnode_t *dnode2 = dnodes2;
|
const bsp2_dnode_t *dnode2 = dnodes2;
|
||||||
|
|
@ -1675,8 +1755,8 @@ BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
|
||||||
dnode29->children[0] = dnode2->children[0];
|
dnode29->children[0] = dnode2->children[0];
|
||||||
dnode29->children[1] = dnode2->children[1];
|
dnode29->children[1] = dnode2->children[1];
|
||||||
for (j = 0; j < 3; j++) {
|
for (j = 0; j < 3; j++) {
|
||||||
dnode29->mins[j] = dnode2->mins[j];
|
dnode29->mins[j] = floor(dnode2->mins[j]);
|
||||||
dnode29->maxs[j] = dnode2->maxs[j];
|
dnode29->maxs[j] = ceil(dnode2->maxs[j]);
|
||||||
}
|
}
|
||||||
dnode29->firstface = dnode2->firstface;
|
dnode29->firstface = dnode2->firstface;
|
||||||
dnode29->numfaces = dnode2->numfaces;
|
dnode29->numfaces = dnode2->numfaces;
|
||||||
|
|
@ -1707,6 +1787,28 @@ BSP29to2_Faces(const bsp29_dface_t *dfaces29, int numfaces) {
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
BSP2to29_Faces_Validate(const bsp2_dface_t *dfaces2, int numfaces) {
|
||||||
|
const bsp2_dface_t *dface2 = dfaces2;
|
||||||
|
|
||||||
|
for (int i = 0; i < numfaces; i++, dface2++) {
|
||||||
|
if (OverflowsInt16(dface2->planenum)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (OverflowsInt16(dface2->side)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (OverflowsInt16(dface2->numedges)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (OverflowsInt16(dface2->texinfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bsp29_dface_t *
|
static bsp29_dface_t *
|
||||||
BSP2to29_Faces(const bsp2_dface_t *dfaces2, int numfaces) {
|
BSP2to29_Faces(const bsp2_dface_t *dfaces2, int numfaces) {
|
||||||
const bsp2_dface_t *dface2 = dfaces2;
|
const bsp2_dface_t *dface2 = dfaces2;
|
||||||
|
|
@ -1749,6 +1851,23 @@ BSP29to2_Clipnodes(const bsp29_dclipnode_t *dclipnodes29, int numclipnodes) {
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
BSP2to29_Clipnodes_Validate(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) {
|
||||||
|
const bsp2_dclipnode_t *dclipnode2 = dclipnodes2;
|
||||||
|
|
||||||
|
for (int i = 0; i < numclipnodes; i++, dclipnode2++) {
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
/* Slightly tricky since we support > 32k clipnodes */
|
||||||
|
int32_t child = dclipnode2->children[j];
|
||||||
|
if (child < -15 || child > 0xFFF0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bsp29_dclipnode_t *
|
static bsp29_dclipnode_t *
|
||||||
BSP2to29_Clipnodes(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) {
|
BSP2to29_Clipnodes(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) {
|
||||||
const bsp2_dclipnode_t *dclipnode2 = dclipnodes2;
|
const bsp2_dclipnode_t *dclipnode2 = dclipnodes2;
|
||||||
|
|
@ -1786,6 +1905,21 @@ BSP29to2_Edges(const bsp29_dedge_t *dedges29, int numedges)
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
BSP2to29_Edges_Validate(const bsp2_dedge_t *dedges2, int numedges)
|
||||||
|
{
|
||||||
|
const bsp2_dedge_t *dedge2 = dedges2;
|
||||||
|
|
||||||
|
for (int i = 0; i < numedges; i++, dedge2++) {
|
||||||
|
if (OverflowsUint16(dedge2->v[0])
|
||||||
|
|| OverflowsUint16(dedge2->v[1])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bsp29_dedge_t *
|
static bsp29_dedge_t *
|
||||||
BSP2to29_Edges(const bsp2_dedge_t *dedges2, int numedges)
|
BSP2to29_Edges(const bsp2_dedge_t *dedges2, int numedges)
|
||||||
{
|
{
|
||||||
|
|
@ -1818,6 +1952,20 @@ BSP29to2_Marksurfaces(const uint16_t *dmarksurfaces29, int nummarksurfaces)
|
||||||
return newdata;
|
return newdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
BSP2to29_Marksurfaces_Validate(const uint32_t *dmarksurfaces2, int nummarksurfaces)
|
||||||
|
{
|
||||||
|
const uint32_t *dmarksurface2 = dmarksurfaces2;
|
||||||
|
|
||||||
|
for (int i = 0; i < nummarksurfaces; i++, dmarksurface2++) {
|
||||||
|
if (OverflowsUint16(*dmarksurface2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static uint16_t *
|
static uint16_t *
|
||||||
BSP2to29_Marksurfaces(const uint32_t *dmarksurfaces2, int nummarksurfaces)
|
BSP2to29_Marksurfaces(const uint32_t *dmarksurfaces2, int nummarksurfaces)
|
||||||
{
|
{
|
||||||
|
|
@ -2209,14 +2357,16 @@ ConvertBSPToMFormatComplete(const bspversion_t **mbsp_loadversion, const bspvers
|
||||||
* - No checks are done here (yet) for overflow of values when down-converting
|
* - No checks are done here (yet) for overflow of values when down-converting
|
||||||
* =========================================================================
|
* =========================================================================
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
{
|
{
|
||||||
if (bspdata->version == to_version)
|
if (bspdata->version == to_version)
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
// conversions to bspver_generic
|
|
||||||
if (to_version == &bspver_generic) {
|
if (to_version == &bspver_generic) {
|
||||||
|
// Conversions to bspver_generic
|
||||||
|
// NOTE: these always succeed
|
||||||
|
|
||||||
if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) {
|
if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) {
|
||||||
// bspver_q1, bspver_h2, bspver_hl -> bspver_generic
|
// bspver_q1, bspver_h2, bspver_hl -> bspver_generic
|
||||||
|
|
||||||
|
|
@ -2269,7 +2419,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (bspdata->version == &bspver_q2) {
|
} else if (bspdata->version == &bspver_q2) {
|
||||||
// bspver_q2 -> bspver_generic
|
// bspver_q2 -> bspver_generic
|
||||||
|
|
||||||
|
|
@ -2327,7 +2477,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (bspdata->version == &bspver_qbism) {
|
} else if (bspdata->version == &bspver_qbism) {
|
||||||
// bspver_qbism -> bspver_generic
|
// bspver_qbism -> bspver_generic
|
||||||
|
|
||||||
|
|
@ -2385,7 +2535,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (bspdata->version == &bspver_bsp2rmq || bspdata->version == &bspver_h2bsp2rmq) {
|
} else if (bspdata->version == &bspver_bsp2rmq || bspdata->version == &bspver_h2bsp2rmq) {
|
||||||
// bspver_bsp2rmq, bspver_h2bsp2rmq -> bspver_generic
|
// bspver_bsp2rmq, bspver_h2bsp2rmq -> bspver_generic
|
||||||
|
|
||||||
|
|
@ -2438,7 +2588,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (bspdata->version == &bspver_bsp2 || bspdata->version == &bspver_h2bsp2) {
|
} else if (bspdata->version == &bspver_bsp2 || bspdata->version == &bspver_h2bsp2) {
|
||||||
// bspver_bsp2, bspver_h2bsp2 -> bspver_generic
|
// bspver_bsp2, bspver_h2bsp2 -> bspver_generic
|
||||||
|
|
||||||
|
|
@ -2491,17 +2641,39 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// conversions from GENERIC_BSP
|
|
||||||
else if (bspdata->version == &bspver_generic) {
|
else if (bspdata->version == &bspver_generic) {
|
||||||
|
// Conversions from bspver_generic
|
||||||
|
|
||||||
if (to_version == &bspver_q1 || to_version == &bspver_h2 || to_version == &bspver_hl) {
|
if (to_version == &bspver_q1 || to_version == &bspver_h2 || to_version == &bspver_hl) {
|
||||||
// bspver_generic -> bspver_q1, bspver_h2, bspver_hl
|
// bspver_generic -> bspver_q1, bspver_h2, bspver_hl
|
||||||
|
|
||||||
bsp29_t *bsp29 = &bspdata->data.bsp29;
|
bsp29_t *bsp29 = &bspdata->data.bsp29;
|
||||||
mbsp_t *mbsp = &bspdata->data.mbsp;
|
mbsp_t *mbsp = &bspdata->data.mbsp;
|
||||||
|
|
||||||
|
// validate that the conversion is possible
|
||||||
|
if (!MBSPto29_Leafs_Validate(mbsp->dleafs, mbsp->numleafs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!BSP2to29_Nodes_Validate(mbsp->dnodes, mbsp->numnodes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!BSP2to29_Faces_Validate(mbsp->dfaces, mbsp->numfaces)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!BSP2to29_Clipnodes_Validate(mbsp->dclipnodes, mbsp->numclipnodes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!BSP2to29_Edges_Validate(mbsp->dedges, mbsp->numedges)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!BSP2to29_Marksurfaces_Validate(mbsp->dleaffaces, mbsp->numleaffaces)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// zero destination struct
|
||||||
memset(bsp29, 0, sizeof(*bsp29));
|
memset(bsp29, 0, sizeof(*bsp29));
|
||||||
|
|
||||||
// copy counts
|
// copy counts
|
||||||
|
|
@ -2548,7 +2720,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
bspdata->version = to_version;
|
bspdata->version = to_version;
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (to_version == &bspver_q2) {
|
} else if (to_version == &bspver_q2) {
|
||||||
// bspver_generic -> bspver_q2
|
// bspver_generic -> bspver_q2
|
||||||
|
|
||||||
|
|
@ -2605,7 +2777,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
bspdata->version = to_version;
|
bspdata->version = to_version;
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (to_version == &bspver_qbism) {
|
} else if (to_version == &bspver_qbism) {
|
||||||
// bspver_generic -> bspver_qbism
|
// bspver_generic -> bspver_qbism
|
||||||
|
|
||||||
|
|
@ -2662,7 +2834,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
bspdata->version = to_version;
|
bspdata->version = to_version;
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (to_version == &bspver_bsp2rmq || to_version == &bspver_h2bsp2rmq) {
|
} else if (to_version == &bspver_bsp2rmq || to_version == &bspver_h2bsp2rmq) {
|
||||||
// bspver_generic -> bspver_bsp2rmq, bspver_h2bsp2rmq
|
// bspver_generic -> bspver_bsp2rmq, bspver_h2bsp2rmq
|
||||||
|
|
||||||
|
|
@ -2715,7 +2887,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
bspdata->version = to_version;
|
bspdata->version = to_version;
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (to_version == &bspver_bsp2 || to_version == &bspver_h2bsp2) {
|
} else if (to_version == &bspver_bsp2 || to_version == &bspver_h2bsp2) {
|
||||||
// bspver_generic -> bspver_bsp2, bspver_h2bsp2
|
// bspver_generic -> bspver_bsp2, bspver_h2bsp2
|
||||||
|
|
||||||
|
|
@ -2768,7 +2940,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
||||||
/* Conversion complete! */
|
/* Conversion complete! */
|
||||||
bspdata->version = to_version;
|
bspdata->version = to_version;
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1025,7 +1025,10 @@ constexpr const bspversion_t *const bspversions[] = {
|
||||||
void LoadBSPFile(char *filename, bspdata_t *bspdata); //returns the filename as contained inside a bsp
|
void LoadBSPFile(char *filename, bspdata_t *bspdata); //returns the filename as contained inside a bsp
|
||||||
void WriteBSPFile(const char *filename, bspdata_t *bspdata);
|
void WriteBSPFile(const char *filename, bspdata_t *bspdata);
|
||||||
void PrintBSPFileSizes(const bspdata_t *bspdata);
|
void PrintBSPFileSizes(const bspdata_t *bspdata);
|
||||||
void ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version);
|
/**
|
||||||
|
* Returns false if the conversion failed.
|
||||||
|
*/
|
||||||
|
bool ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version);
|
||||||
void BSPX_AddLump(bspdata_t *bspdata, const char *xname, const void *xdata, size_t xsize);
|
void BSPX_AddLump(bspdata_t *bspdata, const char *xname, const void *xdata, size_t xsize);
|
||||||
const void *BSPX_GetLump(bspdata_t *bspdata, const char *xname, size_t *xsize);
|
const void *BSPX_GetLump(bspdata_t *bspdata, const char *xname, size_t *xsize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,8 +162,8 @@ typedef struct mapdata_s {
|
||||||
// Final, exported data
|
// Final, exported data
|
||||||
std::vector<gtexinfo_t> exported_texinfos;
|
std::vector<gtexinfo_t> exported_texinfos;
|
||||||
std::vector<dplane_t> exported_planes;
|
std::vector<dplane_t> exported_planes;
|
||||||
std::vector<mleaf_t> exported_leafs_bsp29;
|
std::vector<mleaf_t> exported_leafs;
|
||||||
std::vector<bsp2_dnode_t> exported_nodes_bsp29;
|
std::vector<bsp2_dnode_t> exported_nodes;
|
||||||
std::vector<uint32_t> exported_marksurfaces;
|
std::vector<uint32_t> exported_marksurfaces;
|
||||||
std::vector<bsp2_dclipnode_t> exported_clipnodes;
|
std::vector<bsp2_dclipnode_t> exported_clipnodes;
|
||||||
std::vector<bsp2_dedge_t> exported_edges;
|
std::vector<bsp2_dedge_t> exported_edges;
|
||||||
|
|
@ -177,6 +177,7 @@ typedef struct mapdata_s {
|
||||||
// bspx data
|
// bspx data
|
||||||
std::vector<uint8_t> exported_lmshifts;
|
std::vector<uint8_t> exported_lmshifts;
|
||||||
bool needslmshifts = false;
|
bool needslmshifts = false;
|
||||||
|
std::vector<uint8_t> exported_bspxbrushes;
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
const std::string &miptexTextureName(int mt) const {
|
const std::string &miptexTextureName(int mt) const {
|
||||||
|
|
@ -238,11 +239,8 @@ int MakeFaceEdges(mapentity_t *entity, node_t *headnode);
|
||||||
void ExportClipNodes(mapentity_t *entity, node_t *headnode, const int hullnum);
|
void ExportClipNodes(mapentity_t *entity, node_t *headnode, const int hullnum);
|
||||||
void ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface);
|
void ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface);
|
||||||
|
|
||||||
struct bspxbrushes_s
|
struct bspxbrushes_s {
|
||||||
{
|
std::vector<uint8_t> lumpdata;
|
||||||
uint8_t *lumpinfo;
|
|
||||||
size_t lumpsize;
|
|
||||||
size_t lumpmaxsize;
|
|
||||||
};
|
};
|
||||||
void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx);
|
void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx);
|
||||||
void BSPX_Brushes_Init(struct bspxbrushes_s *ctx);
|
void BSPX_Brushes_Init(struct bspxbrushes_s *ctx);
|
||||||
|
|
|
||||||
31
qbsp/qbsp.cc
31
qbsp/qbsp.cc
|
|
@ -316,14 +316,21 @@ This lump replaces the clipnodes stuff for custom collision sizes.
|
||||||
*/
|
*/
|
||||||
void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx)
|
void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx)
|
||||||
{
|
{
|
||||||
//BSPX_AddLump("BRUSHLIST", ctx->lumpinfo, ctx->lumpsize); // FIXME: fix bspx
|
// Actually written in WriteBSPFile()
|
||||||
|
map.exported_bspxbrushes = std::move(ctx->lumpdata);
|
||||||
// free(ctx->lumpinfo);
|
|
||||||
}
|
}
|
||||||
void BSPX_Brushes_Init(struct bspxbrushes_s *ctx)
|
void BSPX_Brushes_Init(struct bspxbrushes_s *ctx)
|
||||||
{
|
{
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
ctx->lumpdata.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vec_push_bytes(std::vector<uint8_t>& vec, const void* data, size_t count) {
|
||||||
|
const uint8_t* bytes = static_cast<const uint8_t*>(data);
|
||||||
|
|
||||||
|
vec.insert(vec.end(), bytes, bytes + count);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
WriteBrushes
|
WriteBrushes
|
||||||
Generates a submodel's direct brush information to a separate file, so the engine doesn't need to depend upon specific hull sizes
|
Generates a submodel's direct brush information to a separate file, so the engine doesn't need to depend upon specific hull sizes
|
||||||
|
|
@ -372,18 +379,11 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->lumpmaxsize < ctx->lumpsize + sizeof(permodel) + permodel.numbrushes*sizeof(perbrush) + permodel.numfaces*sizeof(perface))
|
|
||||||
{
|
|
||||||
ctx->lumpmaxsize = (ctx->lumpsize + sizeof(permodel) + permodel.numbrushes*sizeof(perbrush) + permodel.numfaces*sizeof(perface))*2;
|
|
||||||
ctx->lumpinfo = (uint8_t *) realloc(ctx->lumpinfo, ctx->lumpmaxsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
permodel.ver = LittleLong(1);
|
permodel.ver = LittleLong(1);
|
||||||
permodel.modelnum = LittleLong(modelnum);
|
permodel.modelnum = LittleLong(modelnum);
|
||||||
permodel.numbrushes = LittleLong(permodel.numbrushes);
|
permodel.numbrushes = LittleLong(permodel.numbrushes);
|
||||||
permodel.numfaces = LittleLong(permodel.numfaces);
|
permodel.numfaces = LittleLong(permodel.numfaces);
|
||||||
memcpy(ctx->lumpinfo+ctx->lumpsize, &permodel, sizeof(permodel));
|
vec_push_bytes(ctx->lumpdata, &permodel, sizeof(permodel));
|
||||||
ctx->lumpsize += sizeof(permodel);
|
|
||||||
|
|
||||||
for (b = brushes; b; b = b->next)
|
for (b = brushes; b; b = b->next)
|
||||||
{
|
{
|
||||||
|
|
@ -426,8 +426,7 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru
|
||||||
}
|
}
|
||||||
perbrush.contents = LittleShort(perbrush.contents);
|
perbrush.contents = LittleShort(perbrush.contents);
|
||||||
perbrush.numfaces = LittleShort(perbrush.numfaces);
|
perbrush.numfaces = LittleShort(perbrush.numfaces);
|
||||||
memcpy(ctx->lumpinfo+ctx->lumpsize, &perbrush, sizeof(perbrush));
|
vec_push_bytes(ctx->lumpdata, &perbrush, sizeof(perbrush));
|
||||||
ctx->lumpsize += sizeof(perbrush);
|
|
||||||
|
|
||||||
for (f = b->faces; f; f = f->next)
|
for (f = b->faces; f; f = f->next)
|
||||||
{
|
{
|
||||||
|
|
@ -452,11 +451,11 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru
|
||||||
perface.dist = map.planes[f->planenum].dist;
|
perface.dist = map.planes[f->planenum].dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ctx->lumpinfo+ctx->lumpsize, &perface, sizeof(perface));
|
vec_push_bytes(ctx->lumpdata, &perface, sizeof(perface));
|
||||||
ctx->lumpsize += sizeof(perface);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for generating BRUSHLIST bspx lump */
|
/* for generating BRUSHLIST bspx lump */
|
||||||
static void BSPX_CreateBrushList(void)
|
static void BSPX_CreateBrushList(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -223,8 +223,8 @@ ExportLeaf
|
||||||
static void
|
static void
|
||||||
ExportLeaf(mapentity_t *entity, node_t *node)
|
ExportLeaf(mapentity_t *entity, node_t *node)
|
||||||
{
|
{
|
||||||
map.exported_leafs_bsp29.push_back({});
|
map.exported_leafs.push_back({});
|
||||||
mleaf_t *dleaf = &map.exported_leafs_bsp29.back();
|
mleaf_t *dleaf = &map.exported_leafs.back();
|
||||||
|
|
||||||
dleaf->contents = RemapContentsForExport(node->contents);
|
dleaf->contents = RemapContentsForExport(node->contents);
|
||||||
AssertVanillaContentType(dleaf->contents);
|
AssertVanillaContentType(dleaf->contents);
|
||||||
|
|
@ -232,9 +232,9 @@ ExportLeaf(mapentity_t *entity, node_t *node)
|
||||||
/*
|
/*
|
||||||
* write bounding box info
|
* write bounding box info
|
||||||
*/
|
*/
|
||||||
for (int32_t i = 0; i < 3; i++) {
|
for (int32_t i = 0; i < 3; ++i) {
|
||||||
dleaf->mins[i] = node->mins[i];
|
dleaf->mins[i] = floor(node->mins[i]);
|
||||||
dleaf->maxs[i] = node->maxs[i];
|
dleaf->maxs[i] = ceil(node->maxs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dleaf->visofs = -1; // no vis info yet
|
dleaf->visofs = -1; // no vis info yet
|
||||||
|
|
@ -272,14 +272,15 @@ ExportDrawNodes(mapentity_t *entity, node_t *node)
|
||||||
bsp2_dnode_t *dnode;
|
bsp2_dnode_t *dnode;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
const size_t ourNodeIndex = map.exported_nodes_bsp29.size();
|
const size_t ourNodeIndex = map.exported_nodes.size();
|
||||||
map.exported_nodes_bsp29.push_back({});
|
map.exported_nodes.push_back({});
|
||||||
|
|
||||||
dnode = &map.exported_nodes_bsp29[ourNodeIndex];
|
dnode = &map.exported_nodes[ourNodeIndex];
|
||||||
|
|
||||||
for (int32_t i = 0; i < 3; i++) {
|
// VectorCopy doesn't work since dest are shorts
|
||||||
dnode->mins[i] = node->mins[i];
|
for (int32_t i = 0; i < 3; ++i) {
|
||||||
dnode->maxs[i] = node->maxs[i];
|
dnode->mins[i] = floor(node->mins[i]);
|
||||||
|
dnode->maxs[i] = ceil(node->maxs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dnode->planenum = ExportMapPlane(node->planenum);
|
dnode->planenum = ExportMapPlane(node->planenum);
|
||||||
|
|
@ -294,19 +295,19 @@ ExportDrawNodes(mapentity_t *entity, node_t *node)
|
||||||
if (options.target_version->game != GAME_QUAKE_II && node->children[i]->contents == CONTENTS_SOLID)
|
if (options.target_version->game != GAME_QUAKE_II && node->children[i]->contents == CONTENTS_SOLID)
|
||||||
dnode->children[i] = -1;
|
dnode->children[i] = -1;
|
||||||
else {
|
else {
|
||||||
int nextLeafIndex = static_cast<int>(map.exported_leafs_bsp29.size());
|
int nextLeafIndex = static_cast<int>(map.exported_leafs.size());
|
||||||
const int childnum = -(nextLeafIndex + 1);
|
const int childnum = -(nextLeafIndex + 1);
|
||||||
dnode->children[i] = childnum;
|
dnode->children[i] = childnum;
|
||||||
ExportLeaf(entity, node->children[i]);
|
ExportLeaf(entity, node->children[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const int childnum = static_cast<int>(map.exported_nodes_bsp29.size());
|
const int childnum = static_cast<int>(map.exported_nodes.size());
|
||||||
dnode->children[i] = childnum;
|
dnode->children[i] = childnum;
|
||||||
ExportDrawNodes(entity, node->children[i]);
|
ExportDrawNodes(entity, node->children[i]);
|
||||||
|
|
||||||
// Important: our dnode pointer may be invalid after the recursive call, if the vector got resized.
|
// Important: our dnode pointer may be invalid after the recursive call, if the vector got resized.
|
||||||
// So re-set the pointer.
|
// So re-set the pointer.
|
||||||
dnode = &map.exported_nodes_bsp29[ourNodeIndex];
|
dnode = &map.exported_nodes[ourNodeIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -331,11 +332,11 @@ ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface)
|
||||||
|
|
||||||
// populate model struct (which was emitted previously)
|
// populate model struct (which was emitted previously)
|
||||||
dmodel = &map.exported_models.at(static_cast<size_t>(entity->outputmodelnumber));
|
dmodel = &map.exported_models.at(static_cast<size_t>(entity->outputmodelnumber));
|
||||||
dmodel->headnode[0] = static_cast<int>(map.exported_nodes_bsp29.size());
|
dmodel->headnode[0] = static_cast<int>(map.exported_nodes.size());
|
||||||
dmodel->firstface = firstface;
|
dmodel->firstface = firstface;
|
||||||
dmodel->numfaces = static_cast<int>(map.exported_faces.size()) - firstface;
|
dmodel->numfaces = static_cast<int>(map.exported_faces.size()) - firstface;
|
||||||
|
|
||||||
const size_t mapleafsAtStart = map.exported_leafs_bsp29.size();
|
const size_t mapleafsAtStart = map.exported_leafs.size();
|
||||||
|
|
||||||
if (headnode->planenum == PLANENUM_LEAF)
|
if (headnode->planenum == PLANENUM_LEAF)
|
||||||
ExportLeaf(entity, headnode);
|
ExportLeaf(entity, headnode);
|
||||||
|
|
@ -343,7 +344,7 @@ ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface)
|
||||||
ExportDrawNodes(entity, headnode);
|
ExportDrawNodes(entity, headnode);
|
||||||
|
|
||||||
// count how many leafs were exported by the above calls
|
// count how many leafs were exported by the above calls
|
||||||
dmodel->visleafs = static_cast<int>(map.exported_leafs_bsp29.size() - mapleafsAtStart);
|
dmodel->visleafs = static_cast<int>(map.exported_leafs.size() - mapleafsAtStart);
|
||||||
|
|
||||||
/* remove the headnode padding */
|
/* remove the headnode padding */
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
|
|
@ -367,9 +368,9 @@ BeginBSPFile(void)
|
||||||
Q_assert(map.exported_edges.size() == 1);
|
Q_assert(map.exported_edges.size() == 1);
|
||||||
|
|
||||||
// Leave room for leaf 0 (must be solid)
|
// Leave room for leaf 0 (must be solid)
|
||||||
map.exported_leafs_bsp29.push_back({});
|
map.exported_leafs.push_back({});
|
||||||
map.exported_leafs_bsp29.back().contents = RemapContentsForExport(CONTENTS_SOLID);
|
map.exported_leafs.back().contents = RemapContentsForExport(CONTENTS_SOLID);
|
||||||
Q_assert(map.exported_leafs_bsp29.size() == 1);
|
Q_assert(map.exported_leafs.size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -463,9 +464,9 @@ WriteBSPFile()
|
||||||
bspdata.version = &bspver_generic;
|
bspdata.version = &bspver_generic;
|
||||||
|
|
||||||
CopyVector(map.exported_planes, &bspdata.data.mbsp.numplanes, &bspdata.data.mbsp.dplanes);
|
CopyVector(map.exported_planes, &bspdata.data.mbsp.numplanes, &bspdata.data.mbsp.dplanes);
|
||||||
CopyVector(map.exported_leafs_bsp29, &bspdata.data.mbsp.numleafs, &bspdata.data.mbsp.dleafs);
|
CopyVector(map.exported_leafs, &bspdata.data.mbsp.numleafs, &bspdata.data.mbsp.dleafs);
|
||||||
CopyVector(map.exported_vertexes, &bspdata.data.mbsp.numvertexes, &bspdata.data.mbsp.dvertexes);
|
CopyVector(map.exported_vertexes, &bspdata.data.mbsp.numvertexes, &bspdata.data.mbsp.dvertexes);
|
||||||
CopyVector(map.exported_nodes_bsp29, &bspdata.data.mbsp.numnodes, &bspdata.data.mbsp.dnodes);
|
CopyVector(map.exported_nodes, &bspdata.data.mbsp.numnodes, &bspdata.data.mbsp.dnodes);
|
||||||
CopyVector(map.exported_texinfos, &bspdata.data.mbsp.numtexinfo, &bspdata.data.mbsp.texinfo);
|
CopyVector(map.exported_texinfos, &bspdata.data.mbsp.numtexinfo, &bspdata.data.mbsp.texinfo);
|
||||||
CopyVector(map.exported_faces, &bspdata.data.mbsp.numfaces, &bspdata.data.mbsp.dfaces);
|
CopyVector(map.exported_faces, &bspdata.data.mbsp.numfaces, &bspdata.data.mbsp.dfaces);
|
||||||
CopyVector(map.exported_clipnodes, &bspdata.data.mbsp.numclipnodes, &bspdata.data.mbsp.dclipnodes);
|
CopyVector(map.exported_clipnodes, &bspdata.data.mbsp.numclipnodes, &bspdata.data.mbsp.dclipnodes);
|
||||||
|
|
@ -477,15 +478,33 @@ WriteBSPFile()
|
||||||
CopyString(map.exported_entities, true, &bspdata.data.mbsp.entdatasize, (void**)&bspdata.data.mbsp.dentdata);
|
CopyString(map.exported_entities, true, &bspdata.data.mbsp.entdatasize, (void**)&bspdata.data.mbsp.dentdata);
|
||||||
CopyString(map.exported_texdata, false, &bspdata.data.mbsp.texdatasize, (void**)&bspdata.data.mbsp.dtexdata);
|
CopyString(map.exported_texdata, false, &bspdata.data.mbsp.texdatasize, (void**)&bspdata.data.mbsp.dtexdata);
|
||||||
|
|
||||||
|
if (map.needslmshifts) {
|
||||||
|
BSPX_AddLump(&bspdata, "LMSHIFT", map.exported_lmshifts.data(), map.exported_lmshifts.size());
|
||||||
|
}
|
||||||
|
if (!map.exported_bspxbrushes.empty()) {
|
||||||
|
BSPX_AddLump(&bspdata, "BRUSHLIST", map.exported_bspxbrushes.data(), map.exported_bspxbrushes.size());
|
||||||
|
}
|
||||||
|
|
||||||
bspdata.data.mbsp.numareas = 1;
|
bspdata.data.mbsp.numareas = 1;
|
||||||
bspdata.data.mbsp.dareas = (darea_t *) malloc(sizeof(darea_t));
|
bspdata.data.mbsp.dareas = (darea_t *) malloc(sizeof(darea_t));
|
||||||
bspdata.data.mbsp.dareas->firstareaportal = bspdata.data.mbsp.dareas->numareaportals = 0;
|
bspdata.data.mbsp.dareas->firstareaportal = bspdata.data.mbsp.dareas->numareaportals = 0;
|
||||||
|
if (!ConvertBSPFormat(&bspdata, options.target_version)) {
|
||||||
|
const bspversion_t* highLimitsFormat = nullptr;
|
||||||
|
|
||||||
// TODO: pass bspx lumps to generic bsp code so they are written
|
if (options.target_version == &bspver_q1) {
|
||||||
|
highLimitsFormat = &bspver_bsp2;
|
||||||
|
} else if (options.target_version == &bspver_h2) {
|
||||||
|
highLimitsFormat = &bspver_h2bsp2;
|
||||||
|
} else if (options.target_version == &bspver_q2) {
|
||||||
|
highLimitsFormat = &bspver_qbism;
|
||||||
|
} else {
|
||||||
|
Error("No high limits version of %s available", options.target_version->name);
|
||||||
|
}
|
||||||
|
|
||||||
//GenLump("LMSHIFT", BSPX_LMSHIFT, 1);
|
logprint("NOTE: limits exceeded for %s - switching to %s\n", options.target_version->name, highLimitsFormat->name);
|
||||||
|
|
||||||
ConvertBSPFormat(&bspdata, options.target_version);
|
Q_assert(ConvertBSPFormat(&bspdata, highLimitsFormat));
|
||||||
|
}
|
||||||
|
|
||||||
StripExtension(options.szBSPName);
|
StripExtension(options.szBSPName);
|
||||||
strcat(options.szBSPName, ".bsp");
|
strcat(options.szBSPName, ".bsp");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
// Game: Quake
|
||||||
|
// Format: Standard
|
||||||
|
// entity 0
|
||||||
|
{
|
||||||
|
"spawnflags" "0"
|
||||||
|
"classname" "worldspawn"
|
||||||
|
"wad" "free_wad.wad"
|
||||||
|
"_sun_mangle" "-60 -35 0"
|
||||||
|
"_sunlight_color" "1 0.631373 0.631373"
|
||||||
|
"_sunlight" "300"
|
||||||
|
"_sunlight2" "300"
|
||||||
|
// brush 0
|
||||||
|
{
|
||||||
|
( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1
|
||||||
|
( -1440 -1600 2512 ) ( 672 -1600 2512 ) ( -1440 -544 2512 ) sky3 0 -80 0 1 1
|
||||||
|
( 672 -544 2544 ) ( 672 -1600 2544 ) ( -1440 -544 2544 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1
|
||||||
|
( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
}
|
||||||
|
// brush 1
|
||||||
|
{
|
||||||
|
( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1
|
||||||
|
( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 -544 3120 ) ( 672 -1600 3120 ) ( -1440 -544 3120 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1
|
||||||
|
( -3072 -544 672 ) ( -3072 -544 640 ) ( -3072 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
}
|
||||||
|
// brush 2
|
||||||
|
{
|
||||||
|
( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
( -1440 480 640 ) ( -1440 480 672 ) ( 672 480 640 ) sky3 0 64 0 1 1
|
||||||
|
( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 -544 2544 ) ( 672 -1600 2544 ) ( -1440 -544 2544 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1
|
||||||
|
( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
}
|
||||||
|
// brush 3
|
||||||
|
{
|
||||||
|
( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1
|
||||||
|
( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 -544 2736 ) ( 672 -1600 2736 ) ( -1440 -544 2736 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 -3456 672 ) ( -1440 -3456 672 ) ( 672 -3456 640 ) sky3 0 64 0 1 1
|
||||||
|
( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
}
|
||||||
|
// brush 4
|
||||||
|
{
|
||||||
|
( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) brownstone 0 0 0 1 1
|
||||||
|
( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) brownstone 0 0 0 1 1
|
||||||
|
( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) brownstone 0 0 0 1 1
|
||||||
|
( 672 -544 752 ) ( 672 -1600 752 ) ( -1440 -544 752 ) brownstone 0 0 0 1 1
|
||||||
|
( 672 512 672 ) ( -1440 512 672 ) ( 672 512 640 ) brownstone 0 0 0 1 1
|
||||||
|
( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) brownstone 0 0 0 1 1
|
||||||
|
}
|
||||||
|
// brush 5
|
||||||
|
{
|
||||||
|
( 1536 -1600 640 ) ( 1536 -544 640 ) ( 1536 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1
|
||||||
|
( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 -544 2576 ) ( 672 -1600 2576 ) ( -1440 -544 2576 ) sky3 0 -64 0 1 1
|
||||||
|
( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1
|
||||||
|
( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// entity 1
|
||||||
|
{
|
||||||
|
"classname" "info_player_start"
|
||||||
|
"origin" "-1952 -2368 776"
|
||||||
|
}
|
||||||
|
// entity 2
|
||||||
|
{
|
||||||
|
"classname" "func_detail"
|
||||||
|
"_phong" "1"
|
||||||
|
// brush 0
|
||||||
|
{
|
||||||
|
( -1616 -2272 752 ) ( -1616 -2271 752 ) ( -1616 -2272 753 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2256 912 ) ( -1600 -2272 1040 ) ( -1600 -2272 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1600 -2160 912 ) ( -1616 -2176 1040 ) ( -1616 -2176 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2272 752 ) ( -1616 -2272 753 ) ( -1615 -2272 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2272 752 ) ( -1615 -2272 752 ) ( -1616 -2271 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2160 912 ) ( -1488 -2159 912 ) ( -1487 -2160 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2160 768 ) ( -1487 -2160 768 ) ( -1488 -2160 769 ) bolt1 0 0 0 1 1
|
||||||
|
( -1584 -2176 912 ) ( -1584 -2208 912 ) ( -1584 -2208 1040 ) bolt1 0 0 0 1 1
|
||||||
|
}
|
||||||
|
// brush 1
|
||||||
|
{
|
||||||
|
( -1584 -2176 912 ) ( -1584 -2208 1040 ) ( -1584 -2208 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2256 752 ) ( -1616 -2256 753 ) ( -1615 -2256 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2272 752 ) ( -1615 -2272 752 ) ( -1616 -2271 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2160 912 ) ( -1488 -2159 912 ) ( -1487 -2160 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2176 768 ) ( -1487 -2176 768 ) ( -1488 -2176 769 ) bolt1 0 0 0 1 1
|
||||||
|
( -1536 -2176 912 ) ( -1536 -2208 912 ) ( -1536 -2208 1040 ) bolt1 0 0 0 1 1
|
||||||
|
}
|
||||||
|
// brush 2
|
||||||
|
{
|
||||||
|
( -1536 -2176 912 ) ( -1536 -2208 1040 ) ( -1536 -2208 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2272 752 ) ( -1616 -2272 753 ) ( -1615 -2272 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2272 752 ) ( -1615 -2272 752 ) ( -1616 -2271 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2160 912 ) ( -1488 -2159 912 ) ( -1487 -2160 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2160 768 ) ( -1487 -2160 768 ) ( -1488 -2160 769 ) bolt1 0 0 0 1 1
|
||||||
|
( -1504 -2272 912 ) ( -1488 -2256 1040 ) ( -1488 -2256 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2176 912 ) ( -1504 -2160 1040 ) ( -1504 -2160 912 ) bolt1 0 0 0 1 1
|
||||||
|
( -1488 -2160 768 ) ( -1488 -2160 769 ) ( -1488 -2159 768 ) bolt1 0 0 0 1 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// entity 3
|
||||||
|
{
|
||||||
|
"classname" "func_detail"
|
||||||
|
// brush 0
|
||||||
|
{
|
||||||
|
( -1616 -2560 752 ) ( -1616 -2559 752 ) ( -1616 -2560 753 ) bolt1 32 0 0 1 1
|
||||||
|
( -1616 -2544 912 ) ( -1600 -2560 1040 ) ( -1600 -2560 912 ) bolt1 32 0 0 1 1
|
||||||
|
( -1600 -2448 912 ) ( -1616 -2464 1040 ) ( -1616 -2464 912 ) bolt1 32 0 0 1 1
|
||||||
|
( -1616 -2560 752 ) ( -1616 -2560 753 ) ( -1615 -2560 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2560 752 ) ( -1615 -2560 752 ) ( -1616 -2559 752 ) bolt1 0 -32 0 1 1
|
||||||
|
( -1488 -2448 912 ) ( -1488 -2447 912 ) ( -1487 -2448 912 ) bolt1 0 -32 0 1 1
|
||||||
|
( -1488 -2448 768 ) ( -1487 -2448 768 ) ( -1488 -2448 769 ) bolt1 0 0 0 1 1
|
||||||
|
( -1584 -2176 912 ) ( -1584 -2208 912 ) ( -1584 -2208 1040 ) bolt1 32 0 0 1 1
|
||||||
|
}
|
||||||
|
// brush 1
|
||||||
|
{
|
||||||
|
( -1584 -2176 912 ) ( -1584 -2208 1040 ) ( -1584 -2208 912 ) bolt1 32 0 0 1 1
|
||||||
|
( -1616 -2544 752 ) ( -1616 -2544 753 ) ( -1615 -2544 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2560 752 ) ( -1615 -2560 752 ) ( -1616 -2559 752 ) bolt1 0 -32 0 1 1
|
||||||
|
( -1488 -2448 912 ) ( -1488 -2447 912 ) ( -1487 -2448 912 ) bolt1 0 -32 0 1 1
|
||||||
|
( -1488 -2464 768 ) ( -1487 -2464 768 ) ( -1488 -2464 769 ) bolt1 0 0 0 1 1
|
||||||
|
( -1536 -2176 912 ) ( -1536 -2208 912 ) ( -1536 -2208 1040 ) bolt1 32 0 0 1 1
|
||||||
|
}
|
||||||
|
// brush 2
|
||||||
|
{
|
||||||
|
( -1536 -2176 912 ) ( -1536 -2208 1040 ) ( -1536 -2208 912 ) bolt1 32 0 0 1 1
|
||||||
|
( -1616 -2560 752 ) ( -1616 -2560 753 ) ( -1615 -2560 752 ) bolt1 0 0 0 1 1
|
||||||
|
( -1616 -2560 752 ) ( -1615 -2560 752 ) ( -1616 -2559 752 ) bolt1 0 -32 0 1 1
|
||||||
|
( -1488 -2448 912 ) ( -1488 -2447 912 ) ( -1487 -2448 912 ) bolt1 0 -32 0 1 1
|
||||||
|
( -1488 -2448 768 ) ( -1487 -2448 768 ) ( -1488 -2448 769 ) bolt1 0 0 0 1 1
|
||||||
|
( -1504 -2560 912 ) ( -1488 -2544 1040 ) ( -1488 -2544 912 ) bolt1 32 0 0 1 1
|
||||||
|
( -1488 -2464 912 ) ( -1504 -2448 1040 ) ( -1504 -2448 912 ) bolt1 32 0 0 1 1
|
||||||
|
( -1488 -2448 768 ) ( -1488 -2448 769 ) ( -1488 -2447 768 ) bolt1 32 0 0 1 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue