From 3bc9b1b0f89c342177909eae1633ba03287e4a2d Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 6 Sep 2021 17:13:37 -0400 Subject: [PATCH] Instead of directly comparing BSP version pointers just for game type, I compacted quake2/hexen2 into a single enum. Feature check in bspver for colored lightmaps, which replaces the many "version == q2 || version == qbism || version == hl". --- common/bspfile.cc | 22 +++++++++++----------- include/common/bspfile.hh | 16 ++++++++++++++-- light/light.cc | 7 ++++--- light/ltface.cc | 5 +++-- qbsp/brush.cc | 4 ++-- qbsp/map.cc | 12 ++++++------ qbsp/qbsp.cc | 25 ++++++++++--------------- qbsp/writebsp.cc | 8 +++++--- 8 files changed, 55 insertions(+), 44 deletions(-) diff --git a/common/bspfile.cc b/common/bspfile.cc index a7225e39..68a33f1c 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -37,18 +37,18 @@ bool q2_surf_needs_subdivision(const surfflags_t &flags) { return flags.native & (Q2_SURF_WARP | Q2_SURF_SKY); } -/* hexen2, quake2, surf_is_lightmapped surf_needs_subdivision */ -const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP", false, false }; -const bspversion_t bspver_q1 { BSPVERSION, NO_VERSION, "bsp29", "Quake BSP", false, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; -const bspversion_t bspver_bsp2 { BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2", false, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; -const bspversion_t bspver_bsp2rmq { BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ", false, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +/* game, colored lightmap, surf_is_lightmapped surf_needs_subdivision */ +const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP", GAME_UNKNOWN }; +const bspversion_t bspver_q1 { BSPVERSION, NO_VERSION, "bsp29", "Quake BSP", GAME_QUAKE, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +const bspversion_t bspver_bsp2 { BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2", GAME_QUAKE, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +const bspversion_t bspver_bsp2rmq { BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ", GAME_QUAKE, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; /* 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", true, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; -const bspversion_t bspver_h2bsp2 { BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen II BSP2", true, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; -const bspversion_t bspver_h2bsp2rmq { BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq", "Hexen II BSP2-RMQ", true, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; -const bspversion_t bspver_hl { BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP", false, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; -const bspversion_t bspver_q2 { Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP", false, true, q2_surf_is_lightmapped, q2_surf_needs_subdivision }; -const bspversion_t bspver_qbism { Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP", false, true, q2_surf_is_lightmapped, q2_surf_needs_subdivision }; +const bspversion_t bspver_h2 { BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP", GAME_HEXEN_II, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +const bspversion_t bspver_h2bsp2 { BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen II BSP2", GAME_HEXEN_II, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +const bspversion_t bspver_h2bsp2rmq { BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq", "Hexen II BSP2-RMQ", GAME_HEXEN_II, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +const bspversion_t bspver_hl { BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP", GAME_HALF_LIFE, true, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; +const bspversion_t bspver_q2 { Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP", GAME_QUAKE_II, true, q2_surf_is_lightmapped, q2_surf_needs_subdivision }; +const bspversion_t bspver_qbism { Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP", GAME_QUAKE_II, true, q2_surf_is_lightmapped, q2_surf_needs_subdivision }; static const char * BSPVersionString(const bspversion_t *version) diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 3b2000e6..3392308d 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -968,6 +968,15 @@ typedef struct { bspxentry_t *bspxentries; } bspdata_t; +// native game ID target +enum bspgame_t { + GAME_UNKNOWN, + GAME_QUAKE, + GAME_HEXEN_II, + GAME_HALF_LIFE, + GAME_QUAKE_II +}; + // BSP version struct & instances struct bspversion_t { @@ -979,8 +988,11 @@ struct bspversion_t const char *short_name; /* full display name for printing */ const char *name; - bool hexen2; - bool quake2; + /* game ID */ + bspgame_t game; + /* whether the game natively has a colored lightmap or not */ + /* TODO: move to a game-specific table */ + bool rgb_lightmap; bool (*surf_is_lightmapped)(const surfflags_t &flags); bool (*surf_needs_subdivision)(const surfflags_t &flags); }; diff --git a/light/light.cc b/light/light.cc index 7fa0d000..495918cd 100644 --- a/light/light.cc +++ b/light/light.cc @@ -439,7 +439,7 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale) CalculateVertexNormals(bsp); const qboolean bouncerequired = cfg_static.bounce.boolValue() && (debugmode == debugmode_none || debugmode == debugmode_bounce || debugmode == debugmode_bouncelights); //mxd - const qboolean isQuake2map = (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism); //mxd + const qboolean isQuake2map = bsp->loadversion->game == GAME_QUAKE_II; //mxd if (bouncerequired || isQuake2map) { MakeTextureColors(bsp); @@ -470,7 +470,7 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale) // Transfer greyscale lightmap (or color lightmap for Q2/HL) to the bsp and update lightdatasize if (!litonly) { free(bsp->dlightdata); - if (isQuake2map || bsp->loadversion == &bspver_hl) { + if (bsp->loadversion->rgb_lightmap) { bsp->lightdatasize = lit_file_p; bsp->dlightdata = (uint8_t *)malloc(bsp->lightdatasize); memcpy(bsp->dlightdata, lit_filebase, bsp->lightdatasize); @@ -1234,8 +1234,9 @@ light_main(int argc, const char **argv) if (!onlyents) { - if (loadversion != &bspver_q2 && loadversion != &bspver_qbism && bsp->loadversion != &bspver_hl) //mxd. No lit for Quake 2 + if (!loadversion->rgb_lightmap) { CheckLitNeeded(cfg); + } SetupDirt(cfg); LightWorld(&bspdata, !!lmscaleoverride); diff --git a/light/ltface.cc b/light/ltface.cc index dc910ab8..b9541116 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -3144,9 +3144,10 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const uint8_t *out, *lit, *lux; GetFileSpace(&out, &lit, &lux, size * numstyles); - // q2 support int lightofs; - if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism || bsp->loadversion == &bspver_hl) { + + // Q2/HL native colored lightmaps + if (bsp->loadversion->rgb_lightmap) { lightofs = lit - lit_filebase; } else { lightofs = out - filebase; diff --git a/qbsp/brush.cc b/qbsp/brush.cc index cad0e5d0..b2d5609c 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -487,7 +487,7 @@ CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, (rotate_offset[0] != 0.0 || rotate_offset[1] != 0.0 || rotate_offset[2] != 0.0) && rottype == rotation_t::hipnotic && (hullnum >= 0) // hullnum < 0 corresponds to -wrbrushes clipping hulls - && !options.target_version->hexen2; // never do this in Hexen 2 + && options.target_version->game != GAME_HEXEN_II; // never do this in Hexen 2 if (shouldExpand) { vec_t delta; @@ -930,7 +930,7 @@ brush_t *LoadBrush(const mapentity_t *src, const mapbrush_t *mapbrush, int conte facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, rottype, hullnum); } } - else if (options.target_version->hexen2) + else if (options.target_version->game == GAME_HEXEN_II) { if (hullnum == 1) { vec3_t size[2] = { {-16, -16, -32}, {16, 16, 24} }; diff --git a/qbsp/map.cc b/qbsp/map.cc index 6abb1ccd..6e1513ea 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -172,7 +172,7 @@ FindMiptex(const char *name) const char *pathsep; int i; - if (!options.target_version->quake2) { + if (options.target_version->game != GAME_QUAKE_II) { /* Ignore leading path in texture names (Q2 map compatibility) */ pathsep = strrchr(name, '/'); if (pathsep) @@ -185,13 +185,13 @@ FindMiptex(const char *name) } /* Handle animating textures carefully */ - if (!options.target_version->quake2) { + if (options.target_version->game != GAME_QUAKE_II) { if (name[0] == '+') { AddAnimTex(name); i = map.nummiptex(); } } else { - // load data from Q2 .wal + // TODO: load data from Q2 .wal } map.miptex.push_back({ name }); @@ -306,7 +306,7 @@ FindTexinfoEnt(mtexinfo_t *texinfo, const mapentity_t *entity) const char *texname = map.miptex.at(texinfo->miptex).name.c_str(); const int shadow = atoi(ValueForKey(entity, "_shadow")); // These flags are pulled from surf flags in Q2. - if (!options.target_version->quake2) { + if (options.target_version->game != GAME_QUAKE_II) { if (IsSkipName(texname)) flags.extended |= TEX_EXFLAG_SKIP; if (IsHintName(texname)) @@ -421,8 +421,8 @@ ParseEpair(parser_t *parser, mapentity_t *entity) if (!Q_strcasecmp(epair->value, "info_player_start")) { // Quake II uses multiple starts for level transitions/backtracking. // TODO: instead, this should check targetnames. There should only be - // one info_player_start per targetname. - if (!options.target_version->quake2 && (rgfStartSpots & info_player_start)) + // one info_player_start per targetname in Q2. + if (options.target_version->game != GAME_QUAKE_II && (rgfStartSpots & info_player_start)) Message(msgWarning, warnMultipleStarts); rgfStartSpots |= info_player_start; } else if (!Q_strcasecmp(epair->value, "info_player_deathmatch")) { diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 001b5656..62c01a9e 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -576,7 +576,7 @@ CreateHulls(void) if (options.target_version == &bspver_hl) CreateSingleHull(3); - else if (options.target_version->hexen2) + else if (options.target_version->game == GAME_HEXEN_II) { /*note: h2mp doesn't use hull 2 automatically, however gamecode can explicitly set ent.hull=3 to access it*/ CreateSingleHull(3); CreateSingleHull(4); @@ -596,19 +596,14 @@ EnsureTexturesLoaded() return; wadlist_tried_loading = true; - - // Quake II doesn't use wads, .wal's are loaded from pak/loose files - if (!options.target_version->quake2) { - wadstring = ValueForKey(pWorldEnt(), "_wad"); - if (!wadstring[0]) - wadstring = ValueForKey(pWorldEnt(), "wad"); - if (!wadstring[0]) - Message(msgWarning, warnNoWadKey); - else - WADList_Init(wadstring); - } else { - wadstring = ""; - } + + wadstring = ValueForKey(pWorldEnt(), "_wad"); + if (!wadstring[0]) + wadstring = ValueForKey(pWorldEnt(), "wad"); + if (!wadstring[0]) + Message(msgWarning, warnNoWadKey); + else + WADList_Init(wadstring); if (!wadlist.size()) { if (wadstring[0]) @@ -983,7 +978,7 @@ ParseOptions(char *szOptions) } // force specific flags for Q2 - if (options.target_version->quake2) { + if (options.target_version->game == GAME_QUAKE_II) { options.fNoclip = true; } } diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 2144e19a..2a9903a2 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -30,7 +30,8 @@ static void AssertVanillaContentType(int content) { - if (options.target_version->quake2) { + // TODO + if (options.target_version->game == GAME_QUAKE_II) { return; } @@ -70,7 +71,8 @@ RemapContentsForExport(int content) { content = RemapContentsForExport_(content); - if (options.target_version->quake2) { + // TODO + if (options.target_version->game == GAME_QUAKE_II) { switch (content) { case CONTENTS_EMPTY: return 0; @@ -289,7 +291,7 @@ ExportDrawNodes(mapentity_t *entity, node_t *node) if (node->children[i]->planenum == PLANENUM_LEAF) { // In Q2, all leaves must have their own ID even if they share solidity. // (probably for collision purposes? makes sense given they store leafbrushes) - if (!options.target_version->quake2 && node->children[i]->contents == CONTENTS_SOLID) + if (options.target_version->game != GAME_QUAKE_II && node->children[i]->contents == CONTENTS_SOLID) dnode->children[i] = -1; else { int nextLeafIndex = static_cast(map.exported_leafs_bsp29.size());