Change miptex thingies to handle const as the comment wishes they would

Use optional to properly indicate the intended purpose of optional/"unset" values rather than a magic number (also because for some reason outputnum was stuck at 0 even though it defaults to -1 and I didn't want to debug why)
beginning of Q2 contents
This commit is contained in:
Jonathan 2021-09-07 03:24:16 -04:00
parent 00efa6e67d
commit c16bbf403d
6 changed files with 137 additions and 51 deletions

View File

@ -24,6 +24,7 @@
#include <qbsp/parser.hh> #include <qbsp/parser.hh>
#include <optional>
#include <vector> #include <vector>
typedef struct epair_s { typedef struct epair_s {
@ -196,17 +197,25 @@ void LoadMapFile(void);
mapentity_t LoadExternalMap(const char *filename); mapentity_t LoadExternalMap(const char *filename);
void ConvertMapFile(void); void ConvertMapFile(void);
struct extended_tx_info_t { struct extended_texinfo_t {
bool quark_tx1 = false;
bool quark_tx2 = false;
int contents = 0; int contents = 0;
int flags = 0; int flags = 0;
int value = 0; int value = 0;
}; };
int FindMiptex(const char *name); struct quark_tx_info_t {
int FindTexinfo(const mtexinfo_t &texinfo, surfflags_t flags); bool quark_tx1 = false;
bool quark_tx2 = false;
std::optional<extended_texinfo_t> info;
};
int FindMiptex(const char *name, std::optional<extended_texinfo_t> &extended_info);
inline int FindMiptex(const char *name) {
std::optional<extended_texinfo_t> extended_info;
return FindMiptex(name, extended_info);
}
int FindTexinfo(const mtexinfo_t &texinfo);
void PrintEntity(const mapentity_t *entity); void PrintEntity(const mapentity_t *entity);
const char *ValueForKey(const mapentity_t *entity, const char *key); const char *ValueForKey(const mapentity_t *entity, const char *key);

View File

@ -27,6 +27,7 @@
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <array> #include <array>
#include <optional>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
@ -149,7 +150,7 @@ typedef struct mtexinfo_s {
int32_t miptex = 0; int32_t miptex = 0;
surfflags_t flags = {}; surfflags_t flags = {};
int32_t value = 0; // Q2-specific int32_t value = 0; // Q2-specific
int outputnum = -1; // -1 until added to bsp std::optional<int> outputnum = std::nullopt; // nullopt until added to bsp
constexpr auto as_tuple() const { constexpr auto as_tuple() const {
return std::tie(vecs, miptex, flags, value); return std::tie(vecs, miptex, flags, value);

View File

@ -453,7 +453,7 @@ CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush,
texInfoNew.vecs[0][3] += DotProduct( rotate_offset, vecs[0] ); texInfoNew.vecs[0][3] += DotProduct( rotate_offset, vecs[0] );
texInfoNew.vecs[1][3] += DotProduct( rotate_offset, vecs[1] ); texInfoNew.vecs[1][3] += DotProduct( rotate_offset, vecs[1] );
mapface->texinfo = FindTexinfo(texInfoNew, texInfoNew.flags); mapface->texinfo = FindTexinfo(texInfoNew);
} }
VectorCopy(mapface->plane.normal, plane.normal); VectorCopy(mapface->plane.normal, plane.normal);
@ -845,6 +845,14 @@ Brush_GetContents(const mapbrush_t *mapbrush)
const mtexinfo_t &texinfo = map.mtexinfos.at(mapface.texinfo); const mtexinfo_t &texinfo = map.mtexinfos.at(mapface.texinfo);
texname = map.miptexTextureName(texinfo.miptex).c_str(); texname = map.miptexTextureName(texinfo.miptex).c_str();
// if we were already assigned contents from somewhere else
// (Quake II), use this.
if (mapface.contents) {
return mapface.contents;
} else if (options.target_version->game->id == GAME_QUAKE_II) {
continue;
}
if (!Q_strcasecmp(texname, "origin")) if (!Q_strcasecmp(texname, "origin"))
return CONTENTS_ORIGIN; return CONTENTS_ORIGIN;
if (!Q_strcasecmp(texname, "hint")) if (!Q_strcasecmp(texname, "hint"))
@ -864,7 +872,7 @@ Brush_GetContents(const mapbrush_t *mapbrush)
return CONTENTS_SKY; return CONTENTS_SKY;
} }
//and anything else is assumed to be a regular solid. //and anything else is assumed to be a regular solid.
return CONTENTS_SOLID; return options.target_version->game->id == GAME_QUAKE_II ? Q2_CONTENTS_SOLID : CONTENTS_SOLID;
} }

View File

@ -59,7 +59,7 @@ MakeSkipTexinfo()
mt.flags = { 0, TEX_EXFLAG_SKIP }; mt.flags = { 0, TEX_EXFLAG_SKIP };
memset(&mt.vecs, 0, sizeof(mt.vecs)); memset(&mt.vecs, 0, sizeof(mt.vecs));
return FindTexinfo(mt, mt.flags); return FindTexinfo(mt);
} }
/* /*

View File

@ -26,6 +26,7 @@
#include <list> #include <list>
#include <utility> #include <utility>
#include <cassert> #include <cassert>
#include <optional>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
@ -166,8 +167,35 @@ AddAnimTex(const char *name)
} }
} }
struct wal_t
{
char name[32];
int32_t width, height;
int32_t mip_offsets[MIPLEVELS];
char anim_name[32];
int32_t flags, contents, value;
};
static std::optional<wal_t> LoadWal(const char *name) {
static char buf[1024];
q_snprintf(buf, sizeof(buf), "%stextures/%s.wal", gamedir, name);
FILE *fp = fopen(buf, "rb");
if (!fp)
return std::nullopt;
wal_t wal;
fread(&wal, 1, sizeof(wal), fp);
fclose(fp);
return wal;
}
int int
FindMiptex(const char *name) FindMiptex(const char *name, std::optional<extended_texinfo_t> &extended_info)
{ {
const char *pathsep; const char *pathsep;
int i; int i;
@ -177,24 +205,59 @@ FindMiptex(const char *name)
pathsep = strrchr(name, '/'); pathsep = strrchr(name, '/');
if (pathsep) if (pathsep)
name = pathsep + 1; name = pathsep + 1;
}
for (i = 0; i < map.nummiptex(); i++) { extended_info = extended_texinfo_t { };
if (!Q_strcasecmp(name, map.miptex.at(i).name.c_str()))
return i; for (i = 0; i < map.nummiptex(); i++) {
} const texdata_t &tex = map.miptex.at(i);
if (!Q_strcasecmp(name, tex.name.c_str())) {
return i;
}
}
i = map.miptex.size();
map.miptex.push_back({ name });
/* Handle animating textures carefully */ /* Handle animating textures carefully */
if (options.target_version->game->id != GAME_QUAKE_II) {
if (name[0] == '+') { if (name[0] == '+') {
AddAnimTex(name); AddAnimTex(name);
i = map.nummiptex();
} }
} else { } else {
// TODO: load data from Q2 .wal // load .wal first
std::optional<wal_t> wal = LoadWal(name);
// FIXME: this spams the console if wal not found, because we
// need to load the wal to figure out if it will match anything
// in the list...
if (!wal.has_value()) {
Message(msgLiteral, "Couldn't locate wal for %s\n", name);
wal = wal_t {};
}
extended_info = extended_info.value_or(extended_texinfo_t { wal->contents, wal->flags, wal->value });
for (i = 0; i < map.nummiptex(); i++) {
const texdata_t &tex = map.miptex.at(i);
if (!Q_strcasecmp(name, tex.name.c_str()) &&
tex.flags == extended_info->flags &&
tex.value == extended_info->value) {
return i;
}
}
i = map.miptex.size();
map.miptex.push_back({ name, wal->flags, wal->value });
/* Handle animating textures carefully */
if (wal->anim_name[0]) {
FindMiptex(wal->anim_name);
}
} }
map.miptex.push_back({ name });
return i; return i;
} }
@ -256,7 +319,7 @@ Returns a global texinfo number
=============== ===============
*/ */
int int
FindTexinfo(const mtexinfo_t &texinfo, surfflags_t flags) FindTexinfo(const mtexinfo_t &texinfo)
{ {
// NaN's will break mtexinfo_lookup, since they're being used as a std::map key and don't compare properly with <. // NaN's will break mtexinfo_lookup, since they're being used as a std::map key and don't compare properly with <.
// They should have been stripped out already in ValidateTextureProjection. // They should have been stripped out already in ValidateTextureProjection.
@ -295,9 +358,9 @@ normalize_color_format(vec3_t color)
} }
} }
static int static surfflags_t
FindTexinfoEnt(const mtexinfo_t &texinfo, const mapentity_t *entity) SurfFlagsForEntity(const mtexinfo_t &texinfo, const mapentity_t *entity)
{ {
surfflags_t flags {}; surfflags_t flags {};
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"));
@ -309,6 +372,13 @@ FindTexinfoEnt(const mtexinfo_t &texinfo, const mapentity_t *entity)
flags.extended |= TEX_EXFLAG_HINT; flags.extended |= TEX_EXFLAG_HINT;
if (IsSpecialName(texname)) if (IsSpecialName(texname))
flags.native |= TEX_SPECIAL; flags.native |= TEX_SPECIAL;
} else {
flags.native = texinfo.flags.native;
if (texinfo.flags.native & Q2_SURF_NODRAW)
flags.extended |= TEX_EXFLAG_SKIP;
if (texinfo.flags.native & Q2_SURF_HINT)
flags.extended |= TEX_EXFLAG_HINT;
} }
if (IsNoExpandName(texname)) if (IsNoExpandName(texname))
flags.extended |= TEX_EXFLAG_NOEXPAND; flags.extended |= TEX_EXFLAG_NOEXPAND;
@ -389,8 +459,8 @@ FindTexinfoEnt(const mtexinfo_t &texinfo, const mapentity_t *entity)
if (lightalpha != 0.0) { if (lightalpha != 0.0) {
flags.light_alpha = qclamp((int)rint(lightalpha * 255.0), 0, 255); flags.light_alpha = qclamp((int)rint(lightalpha * 255.0), 0, 255);
} }
return FindTexinfo(texinfo, flags); return flags;
} }
@ -466,10 +536,10 @@ TextureAxisFromPlane(const qbsp_plane_t *plane, vec3_t xv, vec3_t yv, vec3_t sna
VectorCopy(baseaxis[bestaxis * 3], snapped_normal); VectorCopy(baseaxis[bestaxis * 3], snapped_normal);
} }
static extended_tx_info_t static quark_tx_info_t
ParseExtendedTX(parser_t *parser) ParseExtendedTX(parser_t *parser)
{ {
extended_tx_info_t result; quark_tx_info_t result;
if (ParseToken(parser, PARSE_COMMENT | PARSE_OPTIONAL)) { if (ParseToken(parser, PARSE_COMMENT | PARSE_OPTIONAL)) {
if (!strncmp(parser->token, "//TX", 4)) { if (!strncmp(parser->token, "//TX", 4)) {
@ -481,13 +551,14 @@ ParseExtendedTX(parser_t *parser)
} else { } else {
// Parse extra Quake 2 surface info // Parse extra Quake 2 surface info
if (ParseToken(parser, PARSE_OPTIONAL)) { if (ParseToken(parser, PARSE_OPTIONAL)) {
result.contents = atoi(parser->token); result.info = extended_texinfo_t { atoi(parser->token) };
}
if (ParseToken(parser, PARSE_OPTIONAL)) { if (ParseToken(parser, PARSE_OPTIONAL)) {
result.flags = atoi(parser->token); result.info->flags = atoi(parser->token);
} }
if (ParseToken(parser, PARSE_OPTIONAL)) { if (ParseToken(parser, PARSE_OPTIONAL)) {
result.value = atoi(parser->token); result.info->value = atoi(parser->token);
}
} }
} }
@ -1359,7 +1430,7 @@ ParseTextureDef(parser_t *parser, mapface_t &mapface, const mapbrush_t *brush, m
memset(tx, 0, sizeof(*tx)); memset(tx, 0, sizeof(*tx));
extended_tx_info_t extinfo { }; quark_tx_info_t extinfo;
if (brush->format == brushformat_t::BRUSH_PRIMITIVES) { if (brush->format == brushformat_t::BRUSH_PRIMITIVES) {
ParseBrushPrimTX(parser, texMat); ParseBrushPrimTX(parser, texMat);
@ -1372,9 +1443,6 @@ ParseTextureDef(parser_t *parser, mapface_t &mapface, const mapbrush_t *brush, m
// Read extra Q2 params // Read extra Q2 params
extinfo = ParseExtendedTX(parser); extinfo = ParseExtendedTX(parser);
mapface.contents = extinfo.contents;
mapface.flags = { extinfo.flags };
mapface.value = extinfo.value;
} else if (brush->format == brushformat_t::NORMAL) { } else if (brush->format == brushformat_t::NORMAL) {
ParseToken(parser, PARSE_SAMELINE); ParseToken(parser, PARSE_SAMELINE);
mapface.texname = std::string(parser->token); mapface.texname = std::string(parser->token);
@ -1387,9 +1455,6 @@ ParseTextureDef(parser_t *parser, mapface_t &mapface, const mapbrush_t *brush, m
// Read extra Q2 params // Read extra Q2 params
extinfo = ParseExtendedTX(parser); extinfo = ParseExtendedTX(parser);
mapface.contents = extinfo.contents;
mapface.flags = { extinfo.flags };
mapface.value = extinfo.value;
} else { } else {
shift[0] = atof(parser->token); shift[0] = atof(parser->token);
ParseToken(parser, PARSE_SAMELINE); ParseToken(parser, PARSE_SAMELINE);
@ -1410,13 +1475,15 @@ ParseTextureDef(parser_t *parser, mapface_t &mapface, const mapbrush_t *brush, m
} else { } else {
tx_type = TX_QUAKED; tx_type = TX_QUAKED;
} }
mapface.contents = extinfo.contents;
mapface.flags = { extinfo.flags };
mapface.value = extinfo.value;
} }
} }
tx->miptex = FindMiptex(mapface.texname.c_str()); tx->miptex = FindMiptex(mapface.texname.c_str(), extinfo.info);
const auto &miptex = map.miptex[tx->miptex];
mapface.contents = extinfo.info->contents;
tx->flags = mapface.flags = { extinfo.info->flags };
tx->value = mapface.value = extinfo.info->value;
if (!planepts || !plane) if (!planepts || !plane)
return; return;
@ -1479,7 +1546,7 @@ void mapface_t::set_texvecs(const std::array<qvec4f, 2> &vecs)
} }
} }
this->texinfo = FindTexinfo(texInfoNew, texInfoNew.flags); this->texinfo = FindTexinfo(texInfoNew);
} }
bool bool
@ -1570,7 +1637,8 @@ ParseBrushFace(parser_t *parser, const mapbrush_t *brush, const mapentity_t *ent
ValidateTextureProjection(*face, &tx); ValidateTextureProjection(*face, &tx);
face->texinfo = FindTexinfoEnt(tx, entity); tx.flags = SurfFlagsForEntity(tx, entity);
face->texinfo = FindTexinfo(tx);
return face; return face;
} }

View File

@ -124,8 +124,8 @@ int
ExportMapTexinfo(int texinfonum) ExportMapTexinfo(int texinfonum)
{ {
mtexinfo_t *src = &map.mtexinfos.at(texinfonum); mtexinfo_t *src = &map.mtexinfos.at(texinfonum);
if (src->outputnum != -1) if (src->outputnum.has_value())
return src->outputnum; return src->outputnum.value();
// this will be the index of the exported texinfo in the BSP lump // this will be the index of the exported texinfo in the BSP lump
const int i = static_cast<int>(map.exported_texinfos.size()); const int i = static_cast<int>(map.exported_texinfos.size());