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);
}
/* 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)

View File

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

View File

@ -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);

View File

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

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)
&& 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} };

View File

@ -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")) {

View File

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

View File

@ -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<int>(map.exported_leafs_bsp29.size());