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".
This commit is contained in:
Jonathan 2021-09-06 17:13:37 -04:00
parent 8fd1d89b8d
commit 3bc9b1b0f8
8 changed files with 55 additions and 44 deletions

View File

@ -37,18 +37,18 @@ bool q2_surf_needs_subdivision(const surfflags_t &flags) {
return flags.native & (Q2_SURF_WARP | Q2_SURF_SKY); return flags.native & (Q2_SURF_WARP | Q2_SURF_SKY);
} }
/* hexen2, quake2, surf_is_lightmapped surf_needs_subdivision */ /* game, colored lightmap, surf_is_lightmapped surf_needs_subdivision */
const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP", false, false }; 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", false, false, q1_surf_is_lightmapped, q1_surf_needs_subdivision }; 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", false, 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", false, 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 */ /* 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_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", true, 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", true, 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", false, 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", false, true, q2_surf_is_lightmapped, q2_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", false, 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 * static const char *
BSPVersionString(const bspversion_t *version) BSPVersionString(const bspversion_t *version)

View File

@ -968,6 +968,15 @@ typedef struct {
bspxentry_t *bspxentries; bspxentry_t *bspxentries;
} bspdata_t; } 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 // BSP version struct & instances
struct bspversion_t struct bspversion_t
{ {
@ -979,8 +988,11 @@ struct bspversion_t
const char *short_name; const char *short_name;
/* full display name for printing */ /* full display name for printing */
const char *name; const char *name;
bool hexen2; /* game ID */
bool quake2; 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_is_lightmapped)(const surfflags_t &flags);
bool (*surf_needs_subdivision)(const surfflags_t &flags); bool (*surf_needs_subdivision)(const surfflags_t &flags);
}; };

View File

@ -439,7 +439,7 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale)
CalculateVertexNormals(bsp); CalculateVertexNormals(bsp);
const qboolean bouncerequired = cfg_static.bounce.boolValue() && (debugmode == debugmode_none || debugmode == debugmode_bounce || debugmode == debugmode_bouncelights); //mxd 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) { if (bouncerequired || isQuake2map) {
MakeTextureColors(bsp); 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 // Transfer greyscale lightmap (or color lightmap for Q2/HL) to the bsp and update lightdatasize
if (!litonly) { if (!litonly) {
free(bsp->dlightdata); free(bsp->dlightdata);
if (isQuake2map || bsp->loadversion == &bspver_hl) { if (bsp->loadversion->rgb_lightmap) {
bsp->lightdatasize = lit_file_p; bsp->lightdatasize = lit_file_p;
bsp->dlightdata = (uint8_t *)malloc(bsp->lightdatasize); bsp->dlightdata = (uint8_t *)malloc(bsp->lightdatasize);
memcpy(bsp->dlightdata, lit_filebase, bsp->lightdatasize); memcpy(bsp->dlightdata, lit_filebase, bsp->lightdatasize);
@ -1234,8 +1234,9 @@ light_main(int argc, const char **argv)
if (!onlyents) 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); CheckLitNeeded(cfg);
}
SetupDirt(cfg); SetupDirt(cfg);
LightWorld(&bspdata, !!lmscaleoverride); LightWorld(&bspdata, !!lmscaleoverride);

View File

@ -3144,9 +3144,10 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
uint8_t *out, *lit, *lux; uint8_t *out, *lit, *lux;
GetFileSpace(&out, &lit, &lux, size * numstyles); GetFileSpace(&out, &lit, &lux, size * numstyles);
// q2 support
int lightofs; 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; lightofs = lit - lit_filebase;
} else { } else {
lightofs = out - filebase; lightofs = out - filebase;

View File

@ -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) (rotate_offset[0] != 0.0 || rotate_offset[1] != 0.0 || rotate_offset[2] != 0.0)
&& rottype == rotation_t::hipnotic && rottype == rotation_t::hipnotic
&& (hullnum >= 0) // hullnum < 0 corresponds to -wrbrushes clipping hulls && (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) { if (shouldExpand) {
vec_t delta; 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); 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) { if (hullnum == 1) {
vec3_t size[2] = { {-16, -16, -32}, {16, 16, 24} }; vec3_t size[2] = { {-16, -16, -32}, {16, 16, 24} };

View File

@ -172,7 +172,7 @@ FindMiptex(const char *name)
const char *pathsep; const char *pathsep;
int i; int i;
if (!options.target_version->quake2) { if (options.target_version->game != GAME_QUAKE_II) {
/* Ignore leading path in texture names (Q2 map compatibility) */ /* Ignore leading path in texture names (Q2 map compatibility) */
pathsep = strrchr(name, '/'); pathsep = strrchr(name, '/');
if (pathsep) if (pathsep)
@ -185,13 +185,13 @@ FindMiptex(const char *name)
} }
/* Handle animating textures carefully */ /* Handle animating textures carefully */
if (!options.target_version->quake2) { if (options.target_version->game != GAME_QUAKE_II) {
if (name[0] == '+') { if (name[0] == '+') {
AddAnimTex(name); AddAnimTex(name);
i = map.nummiptex(); i = map.nummiptex();
} }
} else { } else {
// load data from Q2 .wal // TODO: load data from Q2 .wal
} }
map.miptex.push_back({ name }); 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 char *texname = map.miptex.at(texinfo->miptex).name.c_str();
const int shadow = atoi(ValueForKey(entity, "_shadow")); const int shadow = atoi(ValueForKey(entity, "_shadow"));
// These flags are pulled from surf flags in Q2. // 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)) if (IsSkipName(texname))
flags.extended |= TEX_EXFLAG_SKIP; flags.extended |= TEX_EXFLAG_SKIP;
if (IsHintName(texname)) if (IsHintName(texname))
@ -421,8 +421,8 @@ ParseEpair(parser_t *parser, mapentity_t *entity)
if (!Q_strcasecmp(epair->value, "info_player_start")) { if (!Q_strcasecmp(epair->value, "info_player_start")) {
// Quake II uses multiple starts for level transitions/backtracking. // Quake II uses multiple starts for level transitions/backtracking.
// TODO: instead, this should check targetnames. There should only be // TODO: instead, this should check targetnames. There should only be
// one info_player_start per targetname. // one info_player_start per targetname in Q2.
if (!options.target_version->quake2 && (rgfStartSpots & info_player_start)) if (options.target_version->game != GAME_QUAKE_II && (rgfStartSpots & info_player_start))
Message(msgWarning, warnMultipleStarts); Message(msgWarning, warnMultipleStarts);
rgfStartSpots |= info_player_start; rgfStartSpots |= info_player_start;
} else if (!Q_strcasecmp(epair->value, "info_player_deathmatch")) { } else if (!Q_strcasecmp(epair->value, "info_player_deathmatch")) {

View File

@ -576,7 +576,7 @@ CreateHulls(void)
if (options.target_version == &bspver_hl) if (options.target_version == &bspver_hl)
CreateSingleHull(3); 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*/ { /*note: h2mp doesn't use hull 2 automatically, however gamecode can explicitly set ent.hull=3 to access it*/
CreateSingleHull(3); CreateSingleHull(3);
CreateSingleHull(4); CreateSingleHull(4);
@ -596,19 +596,14 @@ EnsureTexturesLoaded()
return; return;
wadlist_tried_loading = true; wadlist_tried_loading = true;
// Quake II doesn't use wads, .wal's are loaded from pak/loose files wadstring = ValueForKey(pWorldEnt(), "_wad");
if (!options.target_version->quake2) { if (!wadstring[0])
wadstring = ValueForKey(pWorldEnt(), "_wad"); wadstring = ValueForKey(pWorldEnt(), "wad");
if (!wadstring[0]) if (!wadstring[0])
wadstring = ValueForKey(pWorldEnt(), "wad"); Message(msgWarning, warnNoWadKey);
if (!wadstring[0]) else
Message(msgWarning, warnNoWadKey); WADList_Init(wadstring);
else
WADList_Init(wadstring);
} else {
wadstring = "";
}
if (!wadlist.size()) { if (!wadlist.size()) {
if (wadstring[0]) if (wadstring[0])
@ -983,7 +978,7 @@ ParseOptions(char *szOptions)
} }
// force specific flags for Q2 // force specific flags for Q2
if (options.target_version->quake2) { if (options.target_version->game == GAME_QUAKE_II) {
options.fNoclip = true; options.fNoclip = true;
} }
} }

View File

@ -30,7 +30,8 @@
static void static void
AssertVanillaContentType(int content) AssertVanillaContentType(int content)
{ {
if (options.target_version->quake2) { // TODO
if (options.target_version->game == GAME_QUAKE_II) {
return; return;
} }
@ -70,7 +71,8 @@ RemapContentsForExport(int content)
{ {
content = RemapContentsForExport_(content); content = RemapContentsForExport_(content);
if (options.target_version->quake2) { // TODO
if (options.target_version->game == GAME_QUAKE_II) {
switch (content) { switch (content) {
case CONTENTS_EMPTY: case CONTENTS_EMPTY:
return 0; return 0;
@ -289,7 +291,7 @@ ExportDrawNodes(mapentity_t *entity, node_t *node)
if (node->children[i]->planenum == PLANENUM_LEAF) { if (node->children[i]->planenum == PLANENUM_LEAF) {
// In Q2, all leaves must have their own ID even if they share solidity. // In Q2, all leaves must have their own ID even if they share solidity.
// (probably for collision purposes? makes sense given they store leafbrushes) // (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; dnode->children[i] = -1;
else { else {
int nextLeafIndex = static_cast<int>(map.exported_leafs_bsp29.size()); int nextLeafIndex = static_cast<int>(map.exported_leafs_bsp29.size());