-includeskip for Q2RTX
Fix missing fmt include Default nexttexinfo to -1 to match other tools Fmt support for bspversion_t, use that instead of a static function Cleanup write functions
This commit is contained in:
parent
1b1679fa22
commit
eb4bcf96dc
|
|
@ -25,164 +25,6 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* =========================================================================
|
|
||||||
* ...
|
|
||||||
* =========================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_bsp29[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"texture", sizeof(uint8_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(dmodelq1_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_bsp2rmq[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"texture", sizeof(uint8_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(dmodelq1_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_bsp2[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"texture", sizeof(uint8_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(dmodelq1_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_bsp29_h2[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"texture", sizeof(uint8_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(dmodelh2_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_bsp2rmq_h2[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"texture", sizeof(uint8_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(dmodelh2_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_bsp2_h2[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"texture", sizeof(uint8_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(dmodelh2_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_q2bsp[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(q2_dbrushside_t)},
|
|
||||||
{"pop", sizeof(uint8_t)},
|
|
||||||
{"areas", sizeof(darea_t)},
|
|
||||||
{"areaportals", sizeof(dareaportal_t)},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr lumpspec_t lumpspec_qbism[] = {
|
|
||||||
{"entities", sizeof(char)},
|
|
||||||
{"planes", sizeof(dplane_t)},
|
|
||||||
{"vertexes", sizeof(qvec3f)},
|
|
||||||
{"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(bsp2_dedge_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)},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gamedef_generic_t : public gamedef_t
|
struct gamedef_generic_t : public gamedef_t
|
||||||
{
|
{
|
||||||
gamedef_generic_t() : gamedef_t("") { id = GAME_UNKNOWN; }
|
gamedef_generic_t() : gamedef_t("") { id = GAME_UNKNOWN; }
|
||||||
|
|
@ -576,27 +418,165 @@ struct gamedef_q2_t : public gamedef_t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Game definitions, used for the bsp versions below
|
||||||
static const gamedef_generic_t gamedef_generic;
|
static const gamedef_generic_t gamedef_generic;
|
||||||
const bspversion_t bspver_generic{NO_VERSION, NO_VERSION, "mbsp", "generic BSP", nullptr, &gamedef_generic};
|
|
||||||
static const gamedef_q1_like_t<GAME_QUAKE> gamedef_q1;
|
static const gamedef_q1_like_t<GAME_QUAKE> gamedef_q1;
|
||||||
const bspversion_t bspver_q1{BSPVERSION, NO_VERSION, "bsp29", "Quake BSP", lumpspec_bsp29, &gamedef_q1, &bspver_bsp2};
|
|
||||||
const bspversion_t bspver_bsp2{BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2", lumpspec_bsp2, &gamedef_q1};
|
|
||||||
const bspversion_t bspver_bsp2rmq{
|
|
||||||
BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ", lumpspec_bsp2rmq, &gamedef_q1};
|
|
||||||
/* Hexen II doesn't use a separate version, but we can still use a separate tag/name for it */
|
|
||||||
static const gamedef_h2_t gamedef_h2;
|
static const gamedef_h2_t gamedef_h2;
|
||||||
const bspversion_t bspver_h2{
|
|
||||||
BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP", lumpspec_bsp29_h2, &gamedef_h2, &bspver_h2bsp2};
|
|
||||||
const bspversion_t bspver_h2bsp2{BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen II BSP2", lumpspec_bsp2_h2, &gamedef_h2};
|
|
||||||
const bspversion_t bspver_h2bsp2rmq{
|
|
||||||
BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq", "Hexen II BSP2-RMQ", lumpspec_bsp2rmq_h2, &gamedef_h2};
|
|
||||||
static const gamedef_hl_t gamedef_hl;
|
static const gamedef_hl_t gamedef_hl;
|
||||||
const bspversion_t bspver_hl{BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP", lumpspec_bsp29, &gamedef_hl};
|
|
||||||
static const gamedef_q2_t gamedef_q2;
|
static const gamedef_q2_t gamedef_q2;
|
||||||
|
|
||||||
|
const bspversion_t bspver_generic{NO_VERSION, NO_VERSION, "mbsp", "generic BSP", {}, &gamedef_generic};
|
||||||
|
const bspversion_t bspver_q1{BSPVERSION, NO_VERSION, "bsp29", "Quake BSP", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"texture", sizeof(uint8_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(dmodelq1_t)},
|
||||||
|
}, &gamedef_q1, &bspver_bsp2};
|
||||||
|
const bspversion_t bspver_bsp2{BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"texture", sizeof(uint8_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(dmodelq1_t)},
|
||||||
|
}, &gamedef_q1};
|
||||||
|
const bspversion_t bspver_bsp2rmq{
|
||||||
|
BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"texture", sizeof(uint8_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(dmodelq1_t)},
|
||||||
|
}, &gamedef_q1};
|
||||||
|
/* 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", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"texture", sizeof(uint8_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(dmodelh2_t)},
|
||||||
|
}, &gamedef_h2, &bspver_h2bsp2};
|
||||||
|
const bspversion_t bspver_h2bsp2{BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen II BSP2", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"texture", sizeof(uint8_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(dmodelh2_t)},
|
||||||
|
}, &gamedef_h2};
|
||||||
|
const bspversion_t bspver_h2bsp2rmq{
|
||||||
|
BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq", "Hexen II BSP2-RMQ", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"texture", sizeof(uint8_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(dmodelh2_t)},
|
||||||
|
}, &gamedef_h2};
|
||||||
|
const bspversion_t bspver_hl{BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP", bspver_q1.lumps, &gamedef_hl};
|
||||||
const bspversion_t bspver_q2{
|
const bspversion_t bspver_q2{
|
||||||
Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP", lumpspec_q2bsp, &gamedef_q2, &bspver_qbism};
|
Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(q2_dbrushside_t)},
|
||||||
|
{"pop", sizeof(uint8_t)},
|
||||||
|
{"areas", sizeof(darea_t)},
|
||||||
|
{"areaportals", sizeof(dareaportal_t)},
|
||||||
|
}, &gamedef_q2, &bspver_qbism};
|
||||||
const bspversion_t bspver_qbism{
|
const bspversion_t bspver_qbism{
|
||||||
Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP", lumpspec_qbism, &gamedef_q2};
|
Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP", {
|
||||||
|
{"entities", sizeof(char)},
|
||||||
|
{"planes", sizeof(dplane_t)},
|
||||||
|
{"vertexes", sizeof(qvec3f)},
|
||||||
|
{"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(bsp2_dedge_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)},
|
||||||
|
}, &gamedef_q2};
|
||||||
|
|
||||||
bool contentflags_t::types_equal(const contentflags_t &other, const gamedef_t *game) const
|
bool contentflags_t::types_equal(const contentflags_t &other, const gamedef_t *game) const
|
||||||
{
|
{
|
||||||
|
|
@ -640,23 +620,6 @@ std::string contentflags_t::to_string(const gamedef_t *game) const
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|
||||||
snprintf(buffer, sizeof(buffers[0]), "%d:%d", version->version, version->ident);
|
|
||||||
} else {
|
|
||||||
snprintf(buffer, sizeof(buffers[0]), "%d", version->version);
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool BSPVersionSupported(int32_t ident, int32_t version, const bspversion_t **out_version)
|
static bool BSPVersionSupported(int32_t ident, int32_t version, const bspversion_t **out_version)
|
||||||
{
|
{
|
||||||
for (const bspversion_t *bspver : bspversions) {
|
for (const bspversion_t *bspver : bspversions) {
|
||||||
|
|
@ -928,7 +891,8 @@ struct lump_reader
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void read(size_t lump_num, std::vector<T> &buffer)
|
void read(size_t lump_num, std::vector<T> &buffer)
|
||||||
{
|
{
|
||||||
const lumpspec_t &lumpspec = version->lumps[lump_num];
|
Q_assert(version->lumps.size() > lump_num);
|
||||||
|
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
|
||||||
const lump_t &lump = lumps[lump_num];
|
const lump_t &lump = lumps[lump_num];
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
|
|
@ -963,7 +927,8 @@ struct lump_reader
|
||||||
// read string from stream
|
// read string from stream
|
||||||
void read(size_t lump_num, std::string &buffer)
|
void read(size_t lump_num, std::string &buffer)
|
||||||
{
|
{
|
||||||
const lumpspec_t &lumpspec = version->lumps[lump_num];
|
Q_assert(version->lumps.size() > lump_num);
|
||||||
|
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
|
||||||
const lump_t &lump = lumps[lump_num];
|
const lump_t &lump = lumps[lump_num];
|
||||||
|
|
||||||
Q_assert(lumpspec.size == 1);
|
Q_assert(lumpspec.size == 1);
|
||||||
|
|
@ -988,7 +953,8 @@ struct lump_reader
|
||||||
template<typename T, typename = std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::stream_read)>>>
|
template<typename T, typename = std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::stream_read)>>>
|
||||||
void read(size_t lump_num, T &buffer)
|
void read(size_t lump_num, T &buffer)
|
||||||
{
|
{
|
||||||
const lumpspec_t &lumpspec = version->lumps[lump_num];
|
Q_assert(version->lumps.size() > lump_num);
|
||||||
|
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
|
||||||
const lump_t &lump = lumps[lump_num];
|
const lump_t &lump = lumps[lump_num];
|
||||||
|
|
||||||
if (!lump.filelen)
|
if (!lump.filelen)
|
||||||
|
|
@ -1098,7 +1064,7 @@ void LoadBSPFile(std::filesystem::path &filename, bspdata_t *bspdata)
|
||||||
|
|
||||||
/* check the file version */
|
/* check the file version */
|
||||||
if (!BSPVersionSupported(temp_version.ident, temp_version.version, &bspdata->version)) {
|
if (!BSPVersionSupported(temp_version.ident, temp_version.version, &bspdata->version)) {
|
||||||
LogPrint("BSP is version {}\n", BSPVersionString(&temp_version));
|
LogPrint("BSP is version {}\n", temp_version);
|
||||||
Error("Sorry, this bsp version is not supported.");
|
Error("Sorry, this bsp version is not supported.");
|
||||||
} else {
|
} else {
|
||||||
// special case handling for Hexen II
|
// special case handling for Hexen II
|
||||||
|
|
@ -1112,7 +1078,7 @@ void LoadBSPFile(std::filesystem::path &filename, bspdata_t *bspdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint("BSP is version {}\n", BSPVersionString(bspdata->version));
|
LogPrint("BSP is version {}\n", *bspdata->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
lump_reader reader{stream, bspdata->version, lumps};
|
lump_reader reader{stream, bspdata->version, lumps};
|
||||||
|
|
@ -1183,192 +1149,195 @@ struct bspfile_t
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ofstream stream;
|
std::ofstream stream;
|
||||||
};
|
|
||||||
|
|
||||||
// write structured lump data from vector
|
private:
|
||||||
template<typename T>
|
// write structured lump data from vector
|
||||||
static void WriteLump(bspfile_t &bspfile, size_t lump_num, const std::vector<T> &data)
|
template<typename T>
|
||||||
{
|
inline void write_lump(size_t lump_num, const std::vector<T> &data)
|
||||||
static constexpr char pad[4]{};
|
{
|
||||||
const lumpspec_t &lumpspec = bspfile.version->lumps[lump_num];
|
|
||||||
lump_t *lumps;
|
|
||||||
|
|
||||||
if (bspfile.version->version != NO_VERSION) {
|
|
||||||
lumps = bspfile.q2header.lumps.data();
|
|
||||||
} else {
|
|
||||||
lumps = bspfile.q1header.lumps.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
lump_t &lump = lumps[lump_num];
|
|
||||||
|
|
||||||
lump.fileofs = bspfile.stream.tellp();
|
|
||||||
|
|
||||||
for (auto &v : data)
|
|
||||||
bspfile.stream <= v;
|
|
||||||
|
|
||||||
auto written = static_cast<int32_t>(bspfile.stream.tellp()) - lump.fileofs;
|
|
||||||
|
|
||||||
if (sizeof(T) == 1 || lumpspec.size > 1)
|
|
||||||
Q_assert(written == (lumpspec.size * data.size()));
|
|
||||||
|
|
||||||
lump.filelen = written;
|
|
||||||
|
|
||||||
if (written % 4)
|
|
||||||
bspfile.stream.write(pad, 4 - (written % 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
// write structured string data
|
|
||||||
static void WriteLump(bspfile_t &bspfile, size_t lump_num, const std::string &data)
|
|
||||||
{
|
|
||||||
static constexpr char pad[4]{};
|
|
||||||
const lumpspec_t &lumpspec = bspfile.version->lumps[lump_num];
|
|
||||||
lump_t *lumps;
|
|
||||||
|
|
||||||
Q_assert(lumpspec.size == 1);
|
|
||||||
|
|
||||||
if (bspfile.version->version != NO_VERSION) {
|
|
||||||
lumps = bspfile.q2header.lumps.data();
|
|
||||||
} else {
|
|
||||||
lumps = bspfile.q1header.lumps.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
lump_t &lump = lumps[lump_num];
|
|
||||||
|
|
||||||
lump.fileofs = bspfile.stream.tellp();
|
|
||||||
|
|
||||||
bspfile.stream.write(data.c_str(), data.size() + 1); // null terminator
|
|
||||||
|
|
||||||
auto written = static_cast<int32_t>(bspfile.stream.tellp()) - lump.fileofs;
|
|
||||||
|
|
||||||
Q_assert(written == data.size() + 1);
|
|
||||||
|
|
||||||
lump.filelen = written;
|
|
||||||
|
|
||||||
if (written % 4)
|
|
||||||
bspfile.stream.write(pad, 4 - (written % 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
// write structured lump data
|
|
||||||
template<typename T, typename = std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::stream_write)>>>
|
|
||||||
static void WriteLump(bspfile_t &bspfile, size_t lump_num, const T &data)
|
|
||||||
{
|
|
||||||
static constexpr char pad[4]{};
|
|
||||||
const lumpspec_t &lumpspec = bspfile.version->lumps[lump_num];
|
|
||||||
lump_t *lumps;
|
|
||||||
|
|
||||||
Q_assert(lumpspec.size == 1);
|
|
||||||
|
|
||||||
if (bspfile.version->version != NO_VERSION) {
|
|
||||||
lumps = bspfile.q2header.lumps.data();
|
|
||||||
} else {
|
|
||||||
lumps = bspfile.q1header.lumps.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
lump_t &lump = lumps[lump_num];
|
|
||||||
|
|
||||||
lump.fileofs = bspfile.stream.tellp();
|
|
||||||
|
|
||||||
data.stream_write(bspfile.stream);
|
|
||||||
|
|
||||||
auto written = static_cast<int32_t>(bspfile.stream.tellp()) - lump.fileofs;
|
|
||||||
|
|
||||||
lump.filelen = written;
|
|
||||||
|
|
||||||
if (written % 4)
|
|
||||||
bspfile.stream.write(pad, 4 - (written % 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline void WriteQ1BSP(bspfile_t &bspfile, const T &bsp)
|
|
||||||
{
|
|
||||||
WriteLump(bspfile, LUMP_PLANES, bsp.dplanes);
|
|
||||||
WriteLump(bspfile, LUMP_LEAFS, bsp.dleafs);
|
|
||||||
WriteLump(bspfile, LUMP_VERTEXES, bsp.dvertexes);
|
|
||||||
WriteLump(bspfile, LUMP_NODES, bsp.dnodes);
|
|
||||||
WriteLump(bspfile, LUMP_TEXINFO, bsp.texinfo);
|
|
||||||
WriteLump(bspfile, LUMP_FACES, bsp.dfaces);
|
|
||||||
WriteLump(bspfile, LUMP_CLIPNODES, bsp.dclipnodes);
|
|
||||||
WriteLump(bspfile, LUMP_MARKSURFACES, bsp.dmarksurfaces);
|
|
||||||
WriteLump(bspfile, LUMP_SURFEDGES, bsp.dsurfedges);
|
|
||||||
WriteLump(bspfile, LUMP_EDGES, bsp.dedges);
|
|
||||||
if (std::holds_alternative<dmodelh2_vector>(bsp.dmodels)) {
|
|
||||||
WriteLump(bspfile, LUMP_MODELS, std::get<dmodelh2_vector>(bsp.dmodels));
|
|
||||||
} else {
|
|
||||||
WriteLump(bspfile, LUMP_MODELS, std::get<dmodelq1_vector>(bsp.dmodels));
|
|
||||||
}
|
|
||||||
WriteLump(bspfile, LUMP_LIGHTING, bsp.dlightdata);
|
|
||||||
WriteLump(bspfile, LUMP_VISIBILITY, bsp.dvisdata);
|
|
||||||
WriteLump(bspfile, LUMP_ENTITIES, bsp.dentdata);
|
|
||||||
if (std::holds_alternative<miptexhl_lump>(bsp.dtex)) {
|
|
||||||
WriteLump(bspfile, LUMP_TEXTURES, std::get<miptexhl_lump>(bsp.dtex));
|
|
||||||
} else {
|
|
||||||
WriteLump(bspfile, LUMP_TEXTURES, std::get<miptexq1_lump>(bsp.dtex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline void WriteQ2BSP(bspfile_t &bspfile, const T &bsp)
|
|
||||||
{
|
|
||||||
WriteLump(bspfile, Q2_LUMP_PLANES, bsp.dplanes);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_LEAFS, bsp.dleafs);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_VERTEXES, bsp.dvertexes);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_NODES, bsp.dnodes);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_TEXINFO, bsp.texinfo);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_FACES, bsp.dfaces);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_LEAFFACES, bsp.dleaffaces);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_SURFEDGES, bsp.dsurfedges);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_EDGES, bsp.dedges);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_MODELS, bsp.dmodels);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_LEAFBRUSHES, bsp.dleafbrushes);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_BRUSHES, bsp.dbrushes);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_BRUSHSIDES, bsp.dbrushsides);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_AREAS, bsp.dareas);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_AREAPORTALS, bsp.dareaportals);
|
|
||||||
|
|
||||||
WriteLump(bspfile, Q2_LUMP_LIGHTING, bsp.dlightdata);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_VISIBILITY, bsp.dvis);
|
|
||||||
WriteLump(bspfile, Q2_LUMP_ENTITIES, bsp.dentdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void WriteBSPXLumps(bspdata_t *bspdata, bspfile_t &bspfile)
|
|
||||||
{
|
|
||||||
if (!bspdata->bspx.entries.size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (bspfile.stream.tellp() & 3)
|
|
||||||
FError("BSPX header is misaligned");
|
|
||||||
|
|
||||||
bspfile.stream <= bspx_header_t(bspdata->bspx.entries.size());
|
|
||||||
|
|
||||||
auto bspxheader = bspfile.stream.tellp();
|
|
||||||
|
|
||||||
// write dummy lump headers
|
|
||||||
for (auto &x : bspdata->bspx.entries) {
|
|
||||||
bspfile.stream <= bspx_lump_t{};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<bspx_lump_t> xlumps;
|
|
||||||
xlumps.reserve(bspdata->bspx.entries.size());
|
|
||||||
|
|
||||||
for (auto &x : bspdata->bspx.entries) {
|
|
||||||
static constexpr char pad[4]{};
|
static constexpr char pad[4]{};
|
||||||
|
Q_assert(version->lumps.size() > lump_num);
|
||||||
|
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
|
||||||
|
lump_t *lumps;
|
||||||
|
|
||||||
bspx_lump_t &lump = xlumps.emplace_back();
|
if (version->version != NO_VERSION) {
|
||||||
lump.filelen = x.second.lumpsize;
|
lumps = q2header.lumps.data();
|
||||||
lump.fileofs = bspfile.stream.tellp();
|
} else {
|
||||||
memcpy(lump.lumpname.data(), x.first.c_str(), std::min(x.first.size(), lump.lumpname.size() - 1));
|
lumps = q1header.lumps.data();
|
||||||
|
}
|
||||||
|
|
||||||
bspfile.stream.write(reinterpret_cast<const char *>(x.second.lumpdata.get()), x.second.lumpsize);
|
lump_t &lump = lumps[lump_num];
|
||||||
|
|
||||||
if (x.second.lumpsize % 4)
|
lump.fileofs = stream.tellp();
|
||||||
bspfile.stream.write(pad, 4 - (x.second.lumpsize % 4));
|
|
||||||
|
for (auto &v : data)
|
||||||
|
stream <= v;
|
||||||
|
|
||||||
|
auto written = static_cast<int32_t>(stream.tellp()) - lump.fileofs;
|
||||||
|
|
||||||
|
if (sizeof(T) == 1 || lumpspec.size > 1)
|
||||||
|
Q_assert(written == (lumpspec.size * data.size()));
|
||||||
|
|
||||||
|
lump.filelen = written;
|
||||||
|
|
||||||
|
if (written % 4)
|
||||||
|
stream.write(pad, 4 - (written % 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
bspfile.stream.seekp(bspxheader);
|
// this is only here to satisfy std::visit
|
||||||
|
constexpr void write_lump(size_t, const std::monostate &) { }
|
||||||
|
|
||||||
for (auto &lump : xlumps)
|
// write structured string data
|
||||||
bspfile.stream <= lump;
|
inline void write_lump(size_t lump_num, const std::string &data)
|
||||||
}
|
{
|
||||||
|
Q_assert(version->lumps.size() > lump_num);
|
||||||
|
static constexpr char pad[4]{};
|
||||||
|
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
|
||||||
|
lump_t *lumps;
|
||||||
|
|
||||||
|
Q_assert(lumpspec.size == 1);
|
||||||
|
|
||||||
|
if (version->version != NO_VERSION) {
|
||||||
|
lumps = q2header.lumps.data();
|
||||||
|
} else {
|
||||||
|
lumps = q1header.lumps.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
lump_t &lump = lumps[lump_num];
|
||||||
|
|
||||||
|
lump.fileofs = stream.tellp();
|
||||||
|
|
||||||
|
stream.write(data.c_str(), data.size() + 1); // null terminator
|
||||||
|
|
||||||
|
auto written = static_cast<int32_t>(stream.tellp()) - lump.fileofs;
|
||||||
|
|
||||||
|
Q_assert(written == data.size() + 1);
|
||||||
|
|
||||||
|
lump.filelen = written;
|
||||||
|
|
||||||
|
if (written % 4)
|
||||||
|
stream.write(pad, 4 - (written % 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
// write structured lump data
|
||||||
|
template<typename T, typename = std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::stream_write)>>>
|
||||||
|
inline void write_lump(size_t lump_num, const T &data)
|
||||||
|
{
|
||||||
|
static constexpr char pad[4]{};
|
||||||
|
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
|
||||||
|
lump_t *lumps;
|
||||||
|
|
||||||
|
Q_assert(lumpspec.size == 1);
|
||||||
|
|
||||||
|
if (version->version != NO_VERSION) {
|
||||||
|
lumps = q2header.lumps.data();
|
||||||
|
} else {
|
||||||
|
lumps = q1header.lumps.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
lump_t &lump = lumps[lump_num];
|
||||||
|
|
||||||
|
lump.fileofs = stream.tellp();
|
||||||
|
|
||||||
|
data.stream_write(stream);
|
||||||
|
|
||||||
|
auto written = static_cast<int32_t>(stream.tellp()) - lump.fileofs;
|
||||||
|
|
||||||
|
lump.filelen = written;
|
||||||
|
|
||||||
|
if (written % 4)
|
||||||
|
stream.write(pad, 4 - (written % 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void write_bsp(const mbsp_t &) { FError("Can't write generic BSP"); }
|
||||||
|
inline void write_bsp(const std::monostate &) { FError("No BSP to write"); }
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if_t<std::is_base_of_v<q1bsp_tag_t, T>, int> = 0>
|
||||||
|
inline void write_bsp(const T &bsp)
|
||||||
|
{
|
||||||
|
write_lump(LUMP_PLANES, bsp.dplanes);
|
||||||
|
write_lump(LUMP_LEAFS, bsp.dleafs);
|
||||||
|
write_lump(LUMP_VERTEXES, bsp.dvertexes);
|
||||||
|
write_lump(LUMP_NODES, bsp.dnodes);
|
||||||
|
write_lump(LUMP_TEXINFO, bsp.texinfo);
|
||||||
|
write_lump(LUMP_FACES, bsp.dfaces);
|
||||||
|
write_lump(LUMP_CLIPNODES, bsp.dclipnodes);
|
||||||
|
write_lump(LUMP_MARKSURFACES, bsp.dmarksurfaces);
|
||||||
|
write_lump(LUMP_SURFEDGES, bsp.dsurfedges);
|
||||||
|
write_lump(LUMP_EDGES, bsp.dedges);
|
||||||
|
std::visit([this](auto&& arg) { write_lump(LUMP_MODELS, arg); }, bsp.dmodels);
|
||||||
|
|
||||||
|
write_lump(LUMP_LIGHTING, bsp.dlightdata);
|
||||||
|
write_lump(LUMP_VISIBILITY, bsp.dvisdata);
|
||||||
|
write_lump(LUMP_ENTITIES, bsp.dentdata);
|
||||||
|
std::visit([this](auto&& arg) { write_lump(LUMP_TEXTURES, arg); }, bsp.dtex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if_t<std::is_base_of_v<q2bsp_tag_t, T>, int> = 0>
|
||||||
|
inline void write_bsp(const T &bsp)
|
||||||
|
{
|
||||||
|
write_lump(Q2_LUMP_PLANES, bsp.dplanes);
|
||||||
|
write_lump(Q2_LUMP_LEAFS, bsp.dleafs);
|
||||||
|
write_lump(Q2_LUMP_VERTEXES, bsp.dvertexes);
|
||||||
|
write_lump(Q2_LUMP_NODES, bsp.dnodes);
|
||||||
|
write_lump(Q2_LUMP_TEXINFO, bsp.texinfo);
|
||||||
|
write_lump(Q2_LUMP_FACES, bsp.dfaces);
|
||||||
|
write_lump(Q2_LUMP_LEAFFACES, bsp.dleaffaces);
|
||||||
|
write_lump(Q2_LUMP_SURFEDGES, bsp.dsurfedges);
|
||||||
|
write_lump(Q2_LUMP_EDGES, bsp.dedges);
|
||||||
|
write_lump(Q2_LUMP_MODELS, bsp.dmodels);
|
||||||
|
write_lump(Q2_LUMP_LEAFBRUSHES, bsp.dleafbrushes);
|
||||||
|
write_lump(Q2_LUMP_BRUSHES, bsp.dbrushes);
|
||||||
|
write_lump(Q2_LUMP_BRUSHSIDES, bsp.dbrushsides);
|
||||||
|
write_lump(Q2_LUMP_AREAS, bsp.dareas);
|
||||||
|
write_lump(Q2_LUMP_AREAPORTALS, bsp.dareaportals);
|
||||||
|
|
||||||
|
write_lump(Q2_LUMP_LIGHTING, bsp.dlightdata);
|
||||||
|
write_lump(Q2_LUMP_VISIBILITY, bsp.dvis);
|
||||||
|
write_lump(Q2_LUMP_ENTITIES, bsp.dentdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void write_bspx(const bspdata_t &bspdata)
|
||||||
|
{
|
||||||
|
if (!bspdata.bspx.entries.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (stream.tellp() & 3)
|
||||||
|
FError("BSPX header is misaligned");
|
||||||
|
|
||||||
|
stream <= bspx_header_t(bspdata.bspx.entries.size());
|
||||||
|
|
||||||
|
auto bspxheader = stream.tellp();
|
||||||
|
|
||||||
|
// write dummy lump headers
|
||||||
|
for (auto &x : bspdata.bspx.entries) {
|
||||||
|
stream <= bspx_lump_t{};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bspx_lump_t> xlumps;
|
||||||
|
xlumps.reserve(bspdata.bspx.entries.size());
|
||||||
|
|
||||||
|
for (auto &x : bspdata.bspx.entries) {
|
||||||
|
static constexpr char pad[4]{};
|
||||||
|
|
||||||
|
bspx_lump_t &lump = xlumps.emplace_back();
|
||||||
|
lump.filelen = x.second.lumpsize;
|
||||||
|
lump.fileofs = stream.tellp();
|
||||||
|
memcpy(lump.lumpname.data(), x.first.c_str(), std::min(x.first.size(), lump.lumpname.size() - 1));
|
||||||
|
|
||||||
|
stream.write(reinterpret_cast<const char *>(x.second.lumpdata.get()), x.second.lumpsize);
|
||||||
|
|
||||||
|
if (x.second.lumpsize % 4)
|
||||||
|
stream.write(pad, 4 - (x.second.lumpsize % 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.seekp(bspxheader);
|
||||||
|
|
||||||
|
for (auto &lump : xlumps)
|
||||||
|
stream <= lump;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =============
|
* =============
|
||||||
|
|
@ -1389,7 +1358,7 @@ void WriteBSPFile(const std::filesystem::path &filename, bspdata_t *bspdata)
|
||||||
bspfile.q2header.version = bspfile.version->version;
|
bspfile.q2header.version = bspfile.version->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint("Writing {} as BSP version {}\n", filename, BSPVersionString(bspdata->version));
|
LogPrint("Writing {} as BSP version {}\n", filename, *bspdata->version);
|
||||||
bspfile.stream.open(filename, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
|
bspfile.stream.open(filename, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
|
||||||
|
|
||||||
if (!bspfile.stream)
|
if (!bspfile.stream)
|
||||||
|
|
@ -1404,22 +1373,10 @@ void WriteBSPFile(const std::filesystem::path &filename, bspdata_t *bspdata)
|
||||||
bspfile.stream <= bspfile.q1header;
|
bspfile.stream <= bspfile.q1header;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::holds_alternative<bsp29_t>(bspdata->bsp)) {
|
std::visit([&bspfile](auto&& arg) { bspfile.write_bsp(arg); }, bspdata->bsp);
|
||||||
WriteQ1BSP(bspfile, std::get<bsp29_t>(bspdata->bsp));
|
|
||||||
} else if (std::holds_alternative<bsp2rmq_t>(bspdata->bsp)) {
|
|
||||||
WriteQ1BSP(bspfile, std::get<bsp2rmq_t>(bspdata->bsp));
|
|
||||||
} else if (std::holds_alternative<bsp2_t>(bspdata->bsp)) {
|
|
||||||
WriteQ1BSP(bspfile, std::get<bsp2_t>(bspdata->bsp));
|
|
||||||
} else if (std::holds_alternative<q2bsp_t>(bspdata->bsp)) {
|
|
||||||
WriteQ2BSP(bspfile, std::get<q2bsp_t>(bspdata->bsp));
|
|
||||||
} else if (std::holds_alternative<q2bsp_qbism_t>(bspdata->bsp)) {
|
|
||||||
WriteQ2BSP(bspfile, std::get<q2bsp_qbism_t>(bspdata->bsp));
|
|
||||||
} else {
|
|
||||||
FError("Unknown format");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*BSPX lumps are at a 4-byte alignment after the last of any official lump*/
|
/*BSPX lumps are at a 4-byte alignment after the last of any official lump*/
|
||||||
WriteBSPXLumps(bspdata, bspfile);
|
bspfile.write_bspx(*bspdata);
|
||||||
|
|
||||||
bspfile.stream.seekp(0);
|
bspfile.stream.seekp(0);
|
||||||
|
|
||||||
|
|
@ -1433,30 +1390,29 @@ void WriteBSPFile(const std::filesystem::path &filename, bspdata_t *bspdata)
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
static void PrintLumpSize(const lumpspec_t *lumpspec, int lumptype, int count)
|
inline void PrintLumpSize(const lumpspec_t &lump, size_t count)
|
||||||
{
|
{
|
||||||
const lumpspec_t *lump = &lumpspec[lumptype];
|
LogPrint("{:7} {:<12} {:10}\n", count, lump.name, count * lump.size);
|
||||||
LogPrint("{:7} {:<12} {:10}\n", count, lump->name, count * lump->size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void PrintQ1BSPLumps(const lumpspec_t *lumpspec, const T &bsp)
|
inline void PrintQ1BSPLumps(const std::initializer_list<lumpspec_t> &lumpspec, const T &bsp)
|
||||||
{
|
{
|
||||||
if (std::holds_alternative<dmodelh2_vector>(bsp.dmodels))
|
if (std::holds_alternative<dmodelh2_vector>(bsp.dmodels))
|
||||||
LogPrint("{:7} {:<12}\n", std::get<dmodelh2_vector>(bsp.dmodels).size(), "models");
|
LogPrint("{:7} {:<12}\n", std::get<dmodelh2_vector>(bsp.dmodels).size(), "models");
|
||||||
else
|
else
|
||||||
LogPrint("{:7} {:<12}\n", std::get<dmodelq1_vector>(bsp.dmodels).size(), "models");
|
LogPrint("{:7} {:<12}\n", std::get<dmodelq1_vector>(bsp.dmodels).size(), "models");
|
||||||
|
|
||||||
PrintLumpSize(lumpspec, LUMP_PLANES, bsp.dplanes.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_PLANES], bsp.dplanes.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_VERTEXES, bsp.dvertexes.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_VERTEXES], bsp.dvertexes.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_NODES, bsp.dnodes.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_NODES], bsp.dnodes.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_TEXINFO, bsp.texinfo.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_TEXINFO], bsp.texinfo.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_FACES, bsp.dfaces.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_FACES], bsp.dfaces.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_CLIPNODES, bsp.dclipnodes.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_CLIPNODES], bsp.dclipnodes.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_LEAFS, bsp.dleafs.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_LEAFS], bsp.dleafs.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_MARKSURFACES, bsp.dmarksurfaces.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_MARKSURFACES], bsp.dmarksurfaces.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_EDGES, bsp.dedges.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_EDGES], bsp.dedges.size());
|
||||||
PrintLumpSize(lumpspec, LUMP_SURFEDGES, bsp.dsurfedges.size());
|
PrintLumpSize(lumpspec.begin()[LUMP_SURFEDGES], bsp.dsurfedges.size());
|
||||||
|
|
||||||
if (std::holds_alternative<miptexhl_lump>(bsp.dtex))
|
if (std::holds_alternative<miptexhl_lump>(bsp.dtex))
|
||||||
LogPrint("{:7} {:<12} {:10}\n", "", "textures", std::get<miptexhl_lump>(bsp.dtex).textures.size());
|
LogPrint("{:7} {:<12} {:10}\n", "", "textures", std::get<miptexhl_lump>(bsp.dtex).textures.size());
|
||||||
|
|
@ -1468,24 +1424,24 @@ inline void PrintQ1BSPLumps(const lumpspec_t *lumpspec, const T &bsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void PrintQ2BSPLumps(const lumpspec_t *lumpspec, const T &bsp)
|
inline void PrintQ2BSPLumps(const std::initializer_list<lumpspec_t> &lumpspec, const T &bsp)
|
||||||
{
|
{
|
||||||
LogPrint("{:7} {:<12}\n", bsp.dmodels.size(), "models");
|
LogPrint("{:7} {:<12}\n", bsp.dmodels.size(), "models");
|
||||||
|
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_PLANES, bsp.dplanes.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_PLANES], bsp.dplanes.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_VERTEXES, bsp.dvertexes.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_VERTEXES], bsp.dvertexes.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_NODES, bsp.dnodes.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_NODES], bsp.dnodes.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_TEXINFO, bsp.texinfo.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_TEXINFO], bsp.texinfo.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_FACES, bsp.dfaces.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_FACES], bsp.dfaces.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_LEAFS, bsp.dleafs.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_LEAFS], bsp.dleafs.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_LEAFFACES, bsp.dleaffaces.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_LEAFFACES], bsp.dleaffaces.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_LEAFBRUSHES, bsp.dleafbrushes.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_LEAFBRUSHES], bsp.dleafbrushes.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_EDGES, bsp.dedges.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_EDGES], bsp.dedges.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_SURFEDGES, bsp.dsurfedges.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_SURFEDGES], bsp.dsurfedges.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_BRUSHES, bsp.dbrushes.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_BRUSHES], bsp.dbrushes.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_BRUSHSIDES, bsp.dbrushsides.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_BRUSHSIDES], bsp.dbrushsides.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_AREAS, bsp.dareas.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_AREAS], bsp.dareas.size());
|
||||||
PrintLumpSize(lumpspec, Q2_LUMP_AREAPORTALS, bsp.dareaportals.size());
|
PrintLumpSize(lumpspec.begin()[Q2_LUMP_AREAPORTALS], bsp.dareaportals.size());
|
||||||
|
|
||||||
LogPrint("{:7} {:<12} {:10}\n", "", "lightdata", bsp.dlightdata.size());
|
LogPrint("{:7} {:<12} {:10}\n", "", "lightdata", bsp.dlightdata.size());
|
||||||
LogPrint("{:7} {:<12} {:10}\n", "", "visdata", bsp.dvis.bits.size());
|
LogPrint("{:7} {:<12} {:10}\n", "", "visdata", bsp.dvis.bits.size());
|
||||||
|
|
@ -1500,7 +1456,7 @@ inline void PrintQ2BSPLumps(const lumpspec_t *lumpspec, const T &bsp)
|
||||||
*/
|
*/
|
||||||
void PrintBSPFileSizes(const bspdata_t *bspdata)
|
void PrintBSPFileSizes(const bspdata_t *bspdata)
|
||||||
{
|
{
|
||||||
const lumpspec_t *lumpspec = bspdata->version->lumps;
|
const auto &lumpspec = bspdata->version->lumps;
|
||||||
|
|
||||||
if (std::holds_alternative<q2bsp_t>(bspdata->bsp)) {
|
if (std::holds_alternative<q2bsp_t>(bspdata->bsp)) {
|
||||||
PrintQ2BSPLumps(lumpspec, std::get<q2bsp_t>(bspdata->bsp));
|
PrintQ2BSPLumps(lumpspec, std::get<q2bsp_t>(bspdata->bsp));
|
||||||
|
|
@ -1513,7 +1469,7 @@ void PrintBSPFileSizes(const bspdata_t *bspdata)
|
||||||
} else if (std::holds_alternative<bsp2_t>(bspdata->bsp)) {
|
} else if (std::holds_alternative<bsp2_t>(bspdata->bsp)) {
|
||||||
PrintQ1BSPLumps(lumpspec, std::get<bsp2_t>(bspdata->bsp));
|
PrintQ1BSPLumps(lumpspec, std::get<bsp2_t>(bspdata->bsp));
|
||||||
} else {
|
} else {
|
||||||
Error("Unsupported BSP version: {}", BSPVersionString(bspdata->version));
|
Error("Unsupported BSP version: {}", *bspdata->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &x : bspdata->bspx.entries) {
|
for (auto &x : bspdata->bspx.entries) {
|
||||||
|
|
|
||||||
|
|
@ -829,7 +829,7 @@ struct gtexinfo_t
|
||||||
// q2 only
|
// q2 only
|
||||||
int32_t value; // light emission, etc
|
int32_t value; // light emission, etc
|
||||||
std::array<char, 32> texture; // texture name (textures/*.wal)
|
std::array<char, 32> texture; // texture name (textures/*.wal)
|
||||||
int32_t nexttexinfo; // for animations, -1 = end of chain
|
int32_t nexttexinfo = -1; // for animations, -1 = end of chain
|
||||||
};
|
};
|
||||||
|
|
||||||
struct texinfo_t
|
struct texinfo_t
|
||||||
|
|
@ -1398,7 +1398,10 @@ using dmodelh2_vector = std::vector<dmodelh2_t>;
|
||||||
using miptexq1_lump = dmiptexlump_t<miptex_t>;
|
using miptexq1_lump = dmiptexlump_t<miptex_t>;
|
||||||
using miptexhl_lump = dmiptexlump_t<miptexhl_t>;
|
using miptexhl_lump = dmiptexlump_t<miptexhl_t>;
|
||||||
|
|
||||||
struct bsp29_t
|
// type tag used for type inference
|
||||||
|
struct q1bsp_tag_t { };
|
||||||
|
|
||||||
|
struct bsp29_t : q1bsp_tag_t
|
||||||
{
|
{
|
||||||
std::variant<std::monostate, dmodelq1_vector, dmodelh2_vector> dmodels;
|
std::variant<std::monostate, dmodelq1_vector, dmodelh2_vector> dmodels;
|
||||||
std::vector<uint8_t> dvisdata;
|
std::vector<uint8_t> dvisdata;
|
||||||
|
|
@ -1417,7 +1420,7 @@ struct bsp29_t
|
||||||
std::vector<int32_t> dsurfedges;
|
std::vector<int32_t> dsurfedges;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bsp2rmq_t
|
struct bsp2rmq_t : q1bsp_tag_t
|
||||||
{
|
{
|
||||||
std::variant<std::monostate, dmodelq1_vector, dmodelh2_vector> dmodels;
|
std::variant<std::monostate, dmodelq1_vector, dmodelh2_vector> dmodels;
|
||||||
std::vector<uint8_t> dvisdata;
|
std::vector<uint8_t> dvisdata;
|
||||||
|
|
@ -1436,7 +1439,7 @@ struct bsp2rmq_t
|
||||||
std::vector<int32_t> dsurfedges;
|
std::vector<int32_t> dsurfedges;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bsp2_t
|
struct bsp2_t : q1bsp_tag_t
|
||||||
{
|
{
|
||||||
std::variant<std::monostate, dmodelq1_vector, dmodelh2_vector> dmodels;
|
std::variant<std::monostate, dmodelq1_vector, dmodelh2_vector> dmodels;
|
||||||
std::vector<uint8_t> dvisdata;
|
std::vector<uint8_t> dvisdata;
|
||||||
|
|
@ -1455,7 +1458,10 @@ struct bsp2_t
|
||||||
std::vector<int32_t> dsurfedges;
|
std::vector<int32_t> dsurfedges;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct q2bsp_t
|
// type tag used for type inference
|
||||||
|
struct q2bsp_tag_t { };
|
||||||
|
|
||||||
|
struct q2bsp_t : q2bsp_tag_t
|
||||||
{
|
{
|
||||||
std::vector<q2_dmodel_t> dmodels;
|
std::vector<q2_dmodel_t> dmodels;
|
||||||
|
|
||||||
|
|
@ -1479,7 +1485,7 @@ struct q2bsp_t
|
||||||
std::vector<q2_dbrushside_t> dbrushsides;
|
std::vector<q2_dbrushside_t> dbrushsides;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct q2bsp_qbism_t
|
struct q2bsp_qbism_t : q2bsp_tag_t
|
||||||
{
|
{
|
||||||
std::vector<q2_dmodel_t> dmodels;
|
std::vector<q2_dmodel_t> dmodels;
|
||||||
mvis_t dvis;
|
mvis_t dvis;
|
||||||
|
|
@ -1657,13 +1663,37 @@ struct bspversion_t
|
||||||
/* full display name for printing */
|
/* full display name for printing */
|
||||||
const char *name;
|
const char *name;
|
||||||
/* lump specification */
|
/* lump specification */
|
||||||
const lumpspec_t *lumps;
|
const std::initializer_list<lumpspec_t> lumps;
|
||||||
/* game ptr */
|
/* game ptr */
|
||||||
const gamedef_t *game;
|
const gamedef_t *game;
|
||||||
/* if we surpass the limits of this format, upgrade to this one */
|
/* if we surpass the limits of this format, upgrade to this one */
|
||||||
const bspversion_t *extended_limits;
|
const bspversion_t *extended_limits;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FMT support
|
||||||
|
template<>
|
||||||
|
struct fmt::formatter<bspversion_t>
|
||||||
|
{
|
||||||
|
constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin())
|
||||||
|
{
|
||||||
|
return ctx.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FormatContext>
|
||||||
|
auto format(const bspversion_t &v, FormatContext &ctx) -> decltype(ctx.out())
|
||||||
|
{
|
||||||
|
if (v.name) {
|
||||||
|
return format_to(ctx.out(), "{}", v.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.version != NO_VERSION) {
|
||||||
|
return format_to(ctx.out(), "{}:{}", v.version, v.ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
return format_to(ctx.out(), "{}", v.version, v.ident);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
extern const bspversion_t bspver_generic;
|
extern const bspversion_t bspver_generic;
|
||||||
extern const bspversion_t bspver_q1;
|
extern const bspversion_t bspver_q1;
|
||||||
extern const bspversion_t bspver_h2;
|
extern const bspversion_t bspver_h2;
|
||||||
|
|
|
||||||
|
|
@ -607,9 +607,6 @@ namespace qv
|
||||||
[[nodiscard]] qmat2x2f inverse(const qmat2x2f &input);
|
[[nodiscard]] qmat2x2f inverse(const qmat2x2f &input);
|
||||||
}; // namespace qv
|
}; // namespace qv
|
||||||
|
|
||||||
// FMT support
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
template<size_t N, class T>
|
template<size_t N, class T>
|
||||||
struct fmt::formatter<qvec<N, T>> : formatter<T>
|
struct fmt::formatter<qvec<N, T>> : formatter<T>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,7 @@ public:
|
||||||
bool fContentHack;
|
bool fContentHack;
|
||||||
vec_t worldExtent;
|
vec_t worldExtent;
|
||||||
bool fNoThreads;
|
bool fNoThreads;
|
||||||
|
bool includeSkip;
|
||||||
|
|
||||||
options_t()
|
options_t()
|
||||||
: fNofill(false), fNoclip(false), fNoskip(false), fNodetail(false), fOnlyents(false), fConvertMapFormat(false),
|
: fNofill(false), fNoclip(false), fNoskip(false), fNodetail(false), fOnlyents(false), fConvertMapFormat(false),
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ Detail brushes are omitted from the compile.
|
||||||
Convert a .MAP to a different .MAP format. fmt can be: quake, quake2, valve, bp (brush primitives).
|
Convert a .MAP to a different .MAP format. fmt can be: quake, quake2, valve, bp (brush primitives).
|
||||||
Conversions to "quake" or "quake2" format may not be able to match the texture alignment in the source map, other conversions are lossless.
|
Conversions to "quake" or "quake2" format may not be able to match the texture alignment in the source map, other conversions are lossless.
|
||||||
The converted map is saved to <source map name>-<fmt>.map.
|
The converted map is saved to <source map name>-<fmt>.map.
|
||||||
|
.IP "\fB-includeskip\fP"
|
||||||
|
Emit skip/nodraw faces. Mainly for Q2RTX.
|
||||||
|
|
||||||
.SH "SPECIAL TEXTURE NAMES"
|
.SH "SPECIAL TEXTURE NAMES"
|
||||||
.PP
|
.PP
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ static void ExportObj_Marksurfaces_r(const node_t *node, std::unordered_set<cons
|
||||||
|
|
||||||
for (face_t **markface = node->markfaces; *markface; markface++) {
|
for (face_t **markface = node->markfaces; *markface; markface++) {
|
||||||
face_t *face = *markface;
|
face_t *face = *markface;
|
||||||
|
|
||||||
if (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_SKIP)
|
if (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_SKIP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ static std::vector<std::tuple<size_t, face_t *>> AddBrushBevels(const brush_t *b
|
||||||
|
|
||||||
int32_t planenum = FindPlane(&new_plane.normal[0], new_plane.dist, nullptr);
|
int32_t planenum = FindPlane(&new_plane.normal[0], new_plane.dist, nullptr);
|
||||||
int32_t outputplanenum = ExportMapPlane(planenum);
|
int32_t outputplanenum = ExportMapPlane(planenum);
|
||||||
planes.emplace_back(outputplanenum, nullptr);
|
planes.emplace_back(outputplanenum, b->faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the plane is not in it canonical order, swap it
|
// if the plane is not in it canonical order, swap it
|
||||||
|
|
@ -250,7 +250,7 @@ static std::vector<std::tuple<size_t, face_t *>> AddBrushBevels(const brush_t *b
|
||||||
// add this plane
|
// add this plane
|
||||||
int32_t planenum = FindPlane(¤t.normal[0], current.dist, nullptr);
|
int32_t planenum = FindPlane(¤t.normal[0], current.dist, nullptr);
|
||||||
int32_t outputplanenum = ExportMapPlane(planenum);
|
int32_t outputplanenum = ExportMapPlane(planenum);
|
||||||
planes.emplace_back(outputplanenum, nullptr);
|
planes.emplace_back(outputplanenum, b->faces);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -273,7 +273,7 @@ static void ExportBrushList(const mapentity_t *entity, node_t *node, uint32_t &b
|
||||||
|
|
||||||
for (auto &plane : bevels) {
|
for (auto &plane : bevels) {
|
||||||
map.bsp.dbrushsides.push_back(
|
map.bsp.dbrushsides.push_back(
|
||||||
{(uint32_t)std::get<0>(plane), (int32_t)ExportMapTexinfo(b->faces->texinfo)});
|
{(uint32_t)std::get<0>(plane), (int32_t)ExportMapTexinfo(std::get<1>(plane)->texinfo)});
|
||||||
brush.numsides++;
|
brush.numsides++;
|
||||||
brush_state.total_brush_sides++;
|
brush_state.total_brush_sides++;
|
||||||
}
|
}
|
||||||
|
|
@ -1153,6 +1153,7 @@ PrintOptions
|
||||||
" -omitdetailillusionary func_detail_illusionary brushes are omitted from the compile\n"
|
" -omitdetailillusionary func_detail_illusionary brushes are omitted from the compile\n"
|
||||||
" -omitdetailfence func_detail_fence brushes are omitted from the compile\n"
|
" -omitdetailfence func_detail_fence brushes are omitted from the compile\n"
|
||||||
" -convert <fmt> Convert a .MAP to a different .MAP format. fmt can be: quake, quake2, valve, bp (brush primitives).\n"
|
" -convert <fmt> Convert a .MAP to a different .MAP format. fmt can be: quake, quake2, valve, bp (brush primitives).\n"
|
||||||
|
" -includeskip Include skip/nodraw faces."
|
||||||
" -expand Write hull 1 expanded brushes to expanded.map for debugging\n"
|
" -expand Write hull 1 expanded brushes to expanded.map for debugging\n"
|
||||||
" -leaktest Make compilation fail if the map leaks\n"
|
" -leaktest Make compilation fail if the map leaks\n"
|
||||||
" -contenthack Hack to fix leaks through solids. Causes missing faces in some cases so disabled by default.\n"
|
" -contenthack Hack to fix leaks through solids. Causes missing faces in some cases so disabled by default.\n"
|
||||||
|
|
@ -1378,6 +1379,8 @@ static void ParseOptions(char *szOptions)
|
||||||
|
|
||||||
options.fConvertMapFormat = true;
|
options.fConvertMapFormat = true;
|
||||||
szTok = szTok2;
|
szTok = szTok2;
|
||||||
|
} else if (!Q_strcasecmp(szTok, "includeskip")) {
|
||||||
|
options.includeSkip = true;
|
||||||
} else if (!Q_strcasecmp(szTok, "forceprt1")) {
|
} else if (!Q_strcasecmp(szTok, "forceprt1")) {
|
||||||
options.fForcePRT1 = true;
|
options.fForcePRT1 = true;
|
||||||
LogPrint("WARNING: Forcing creation of PRT1.\n");
|
LogPrint("WARNING: Forcing creation of PRT1.\n");
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,9 @@ FindFaceEdges
|
||||||
*/
|
*/
|
||||||
static void FindFaceEdges(mapentity_t *entity, face_t *face)
|
static void FindFaceEdges(mapentity_t *entity, face_t *face)
|
||||||
{
|
{
|
||||||
if (map.mtexinfos.at(face->texinfo).flags.extended & (TEX_EXFLAG_SKIP | TEX_EXFLAG_HINT))
|
if (!options.includeSkip && (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_SKIP))
|
||||||
|
return;
|
||||||
|
if (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_HINT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
face->outputnumber = std::nullopt;
|
face->outputnumber = std::nullopt;
|
||||||
|
|
@ -349,7 +351,9 @@ static void EmitFace(mapentity_t *entity, face_t *face)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (map.mtexinfos.at(face->texinfo).flags.extended & (TEX_EXFLAG_SKIP | TEX_EXFLAG_HINT))
|
if (!options.includeSkip && (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_SKIP))
|
||||||
|
return;
|
||||||
|
if (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_HINT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// emit a region
|
// emit a region
|
||||||
|
|
@ -404,7 +408,9 @@ static void GrowNodeRegion(mapentity_t *entity, node_t *node)
|
||||||
|
|
||||||
static void CountFace(mapentity_t *entity, face_t *f, size_t &facesCount, size_t &vertexesCount)
|
static void CountFace(mapentity_t *entity, face_t *f, size_t &facesCount, size_t &vertexesCount)
|
||||||
{
|
{
|
||||||
if (map.mtexinfos.at(f->texinfo).flags.extended & (TEX_EXFLAG_SKIP | TEX_EXFLAG_HINT))
|
if (!options.includeSkip && (map.mtexinfos.at(f->texinfo).flags.extended & TEX_EXFLAG_SKIP))
|
||||||
|
return;
|
||||||
|
if (map.mtexinfos.at(f->texinfo).flags.extended & TEX_EXFLAG_HINT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (f->lmshift[1] != 4)
|
if (f->lmshift[1] != 4)
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,8 @@ static void ExportLeaf(mapentity_t *entity, node_t *node)
|
||||||
|
|
||||||
for (face_t **markfaces = node->markfaces; *markfaces; markfaces++) {
|
for (face_t **markfaces = node->markfaces; *markfaces; markfaces++) {
|
||||||
face_t *face = *markfaces;
|
face_t *face = *markfaces;
|
||||||
if (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_SKIP)
|
|
||||||
|
if (!options.includeSkip && (map.mtexinfos.at(face->texinfo).flags.extended & TEX_EXFLAG_SKIP))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* emit a marksurface */
|
/* emit a marksurface */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue