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:
Jonathan 2021-09-06 17:27:42 -04:00
commit 01d1400971
6 changed files with 400 additions and 67 deletions

View File

@ -20,6 +20,7 @@
#include <common/cmdlib.hh>
#include <common/mathlib.hh>
#include <common/bspfile.hh>
#include <cstdint>
bool q1_surf_is_lightmapped(const surfflags_t &flags) {
return !(flags.native & TEX_SPECIAL);
@ -972,6 +973,60 @@ BSP29toM_Leafs(const bsp29_dleaf_t *dleafs29, int numleafs) {
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 *
MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) {
const mleaf_t *mleaf = mleafs;
@ -984,8 +1039,8 @@ MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) {
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->mins[j] = floor(mleaf->mins[j]);
dleaf29->maxs[j] = ceil(mleaf->maxs[j]);
}
dleaf29->firstmarksurface = mleaf->firstmarksurface;
dleaf29->nummarksurfaces = mleaf->nummarksurfaces;
@ -1662,6 +1717,31 @@ BSP29to2_Nodes(const bsp29_dnode_t *dnodes29, int numnodes) {
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 *
BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) {
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[1] = dnode2->children[1];
for (j = 0; j < 3; j++) {
dnode29->mins[j] = dnode2->mins[j];
dnode29->maxs[j] = dnode2->maxs[j];
dnode29->mins[j] = floor(dnode2->mins[j]);
dnode29->maxs[j] = ceil(dnode2->maxs[j]);
}
dnode29->firstface = dnode2->firstface;
dnode29->numfaces = dnode2->numfaces;
@ -1707,6 +1787,28 @@ BSP29to2_Faces(const bsp29_dface_t *dfaces29, int numfaces) {
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 *
BSP2to29_Faces(const bsp2_dface_t *dfaces2, int numfaces) {
const bsp2_dface_t *dface2 = dfaces2;
@ -1749,6 +1851,23 @@ BSP29to2_Clipnodes(const bsp29_dclipnode_t *dclipnodes29, int numclipnodes) {
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 *
BSP2to29_Clipnodes(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) {
const bsp2_dclipnode_t *dclipnode2 = dclipnodes2;
@ -1786,6 +1905,21 @@ BSP29to2_Edges(const bsp29_dedge_t *dedges29, int numedges)
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 *
BSP2to29_Edges(const bsp2_dedge_t *dedges2, int numedges)
{
@ -1818,6 +1952,20 @@ BSP29to2_Marksurfaces(const uint16_t *dmarksurfaces29, int nummarksurfaces)
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 *
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
* =========================================================================
*/
void
bool
ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
{
if (bspdata->version == to_version)
return;
return true;
// conversions to 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) {
// bspver_q1, bspver_h2, bspver_hl -> bspver_generic
@ -2269,7 +2419,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
return;
return true;
} else if (bspdata->version == &bspver_q2) {
// bspver_q2 -> bspver_generic
@ -2327,7 +2477,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
return;
return true;
} else if (bspdata->version == &bspver_qbism) {
// bspver_qbism -> bspver_generic
@ -2385,7 +2535,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
return;
return true;
} else if (bspdata->version == &bspver_bsp2rmq || bspdata->version == &bspver_h2bsp2rmq) {
// bspver_bsp2rmq, bspver_h2bsp2rmq -> bspver_generic
@ -2438,7 +2588,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
return;
return true;
} else if (bspdata->version == &bspver_bsp2 || bspdata->version == &bspver_h2bsp2) {
// bspver_bsp2, bspver_h2bsp2 -> bspver_generic
@ -2491,17 +2641,39 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata);
return;
return true;
}
}
// conversions from GENERIC_BSP
else if (bspdata->version == &bspver_generic) {
// Conversions from bspver_generic
if (to_version == &bspver_q1 || to_version == &bspver_h2 || to_version == &bspver_hl) {
// bspver_generic -> bspver_q1, bspver_h2, bspver_hl
bsp29_t *bsp29 = &bspdata->data.bsp29;
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));
// copy counts
@ -2548,7 +2720,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
bspdata->version = to_version;
return;
return true;
} else if (to_version == &bspver_q2) {
// bspver_generic -> bspver_q2
@ -2605,7 +2777,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
bspdata->version = to_version;
return;
return true;
} else if (to_version == &bspver_qbism) {
// bspver_generic -> bspver_qbism
@ -2662,7 +2834,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
bspdata->version = to_version;
return;
return true;
} else if (to_version == &bspver_bsp2rmq || to_version == &bspver_h2bsp2rmq) {
// bspver_generic -> bspver_bsp2rmq, bspver_h2bsp2rmq
@ -2715,7 +2887,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
bspdata->version = to_version;
return;
return true;
} else if (to_version == &bspver_bsp2 || to_version == &bspver_h2bsp2) {
// bspver_generic -> bspver_bsp2, bspver_h2bsp2
@ -2768,7 +2940,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
/* Conversion complete! */
bspdata->version = to_version;
return;
return true;
}
}

View File

@ -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 WriteBSPFile(const char *filename, 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);
const void *BSPX_GetLump(bspdata_t *bspdata, const char *xname, size_t *xsize);

View File

@ -162,8 +162,8 @@ typedef struct mapdata_s {
// Final, exported data
std::vector<gtexinfo_t> exported_texinfos;
std::vector<dplane_t> exported_planes;
std::vector<mleaf_t> exported_leafs_bsp29;
std::vector<bsp2_dnode_t> exported_nodes_bsp29;
std::vector<mleaf_t> exported_leafs;
std::vector<bsp2_dnode_t> exported_nodes;
std::vector<uint32_t> exported_marksurfaces;
std::vector<bsp2_dclipnode_t> exported_clipnodes;
std::vector<bsp2_dedge_t> exported_edges;
@ -177,6 +177,7 @@ typedef struct mapdata_s {
// bspx data
std::vector<uint8_t> exported_lmshifts;
bool needslmshifts = false;
std::vector<uint8_t> exported_bspxbrushes;
// helpers
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 ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface);
struct bspxbrushes_s
{
uint8_t *lumpinfo;
size_t lumpsize;
size_t lumpmaxsize;
struct bspxbrushes_s {
std::vector<uint8_t> lumpdata;
};
void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx);
void BSPX_Brushes_Init(struct bspxbrushes_s *ctx);

View File

@ -316,14 +316,21 @@ This lump replaces the clipnodes stuff for custom collision sizes.
*/
void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx)
{
//BSPX_AddLump("BRUSHLIST", ctx->lumpinfo, ctx->lumpsize); // FIXME: fix bspx
// free(ctx->lumpinfo);
// Actually written in WriteBSPFile()
map.exported_bspxbrushes = std::move(ctx->lumpdata);
}
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
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.modelnum = LittleLong(modelnum);
permodel.numbrushes = LittleLong(permodel.numbrushes);
permodel.numfaces = LittleLong(permodel.numfaces);
memcpy(ctx->lumpinfo+ctx->lumpsize, &permodel, sizeof(permodel));
ctx->lumpsize += sizeof(permodel);
vec_push_bytes(ctx->lumpdata, &permodel, sizeof(permodel));
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.numfaces = LittleShort(perbrush.numfaces);
memcpy(ctx->lumpinfo+ctx->lumpsize, &perbrush, sizeof(perbrush));
ctx->lumpsize += sizeof(perbrush);
vec_push_bytes(ctx->lumpdata, &perbrush, sizeof(perbrush));
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;
}
memcpy(ctx->lumpinfo+ctx->lumpsize, &perface, sizeof(perface));
ctx->lumpsize += sizeof(perface);
vec_push_bytes(ctx->lumpdata, &perface, sizeof(perface));
}
}
}
/* for generating BRUSHLIST bspx lump */
static void BSPX_CreateBrushList(void)
{

View File

@ -223,8 +223,8 @@ ExportLeaf
static void
ExportLeaf(mapentity_t *entity, node_t *node)
{
map.exported_leafs_bsp29.push_back({});
mleaf_t *dleaf = &map.exported_leafs_bsp29.back();
map.exported_leafs.push_back({});
mleaf_t *dleaf = &map.exported_leafs.back();
dleaf->contents = RemapContentsForExport(node->contents);
AssertVanillaContentType(dleaf->contents);
@ -232,9 +232,9 @@ ExportLeaf(mapentity_t *entity, node_t *node)
/*
* write bounding box info
*/
for (int32_t i = 0; i < 3; i++) {
dleaf->mins[i] = node->mins[i];
dleaf->maxs[i] = node->maxs[i];
for (int32_t i = 0; i < 3; ++i) {
dleaf->mins[i] = floor(node->mins[i]);
dleaf->maxs[i] = ceil(node->maxs[i]);
}
dleaf->visofs = -1; // no vis info yet
@ -272,14 +272,15 @@ ExportDrawNodes(mapentity_t *entity, node_t *node)
bsp2_dnode_t *dnode;
int i;
const size_t ourNodeIndex = map.exported_nodes_bsp29.size();
map.exported_nodes_bsp29.push_back({});
const size_t ourNodeIndex = map.exported_nodes.size();
map.exported_nodes.push_back({});
dnode = &map.exported_nodes_bsp29[ourNodeIndex];
dnode = &map.exported_nodes[ourNodeIndex];
for (int32_t i = 0; i < 3; i++) {
dnode->mins[i] = node->mins[i];
dnode->maxs[i] = node->maxs[i];
// VectorCopy doesn't work since dest are shorts
for (int32_t i = 0; i < 3; ++i) {
dnode->mins[i] = floor(node->mins[i]);
dnode->maxs[i] = ceil(node->maxs[i]);
}
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)
dnode->children[i] = -1;
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);
dnode->children[i] = childnum;
ExportLeaf(entity, node->children[i]);
}
} 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;
ExportDrawNodes(entity, node->children[i]);
// Important: our dnode pointer may be invalid after the recursive call, if the vector got resized.
// 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)
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->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)
ExportLeaf(entity, headnode);
@ -343,7 +344,7 @@ ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface)
ExportDrawNodes(entity, headnode);
// 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 */
for (i = 0; i < 3; i++) {
@ -367,9 +368,9 @@ BeginBSPFile(void)
Q_assert(map.exported_edges.size() == 1);
// Leave room for leaf 0 (must be solid)
map.exported_leafs_bsp29.push_back({});
map.exported_leafs_bsp29.back().contents = RemapContentsForExport(CONTENTS_SOLID);
Q_assert(map.exported_leafs_bsp29.size() == 1);
map.exported_leafs.push_back({});
map.exported_leafs.back().contents = RemapContentsForExport(CONTENTS_SOLID);
Q_assert(map.exported_leafs.size() == 1);
}
/*
@ -463,9 +464,9 @@ WriteBSPFile()
bspdata.version = &bspver_generic;
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_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_faces, &bspdata.data.mbsp.numfaces, &bspdata.data.mbsp.dfaces);
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_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.dareas = (darea_t *) malloc(sizeof(darea_t));
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);
strcat(options.szBSPName, ".bsp");

142
testmaps/phongtest2.map Normal file
View File

@ -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
}
}