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 <optional>
#include <vector>
typedef struct epair_s {
@ -196,17 +197,25 @@ void LoadMapFile(void);
mapentity_t LoadExternalMap(const char *filename);
void ConvertMapFile(void);
struct extended_tx_info_t {
bool quark_tx1 = false;
bool quark_tx2 = false;
struct extended_texinfo_t {
int contents = 0;
int flags = 0;
int value = 0;
};
int FindMiptex(const char *name);
int FindTexinfo(const mtexinfo_t &texinfo, surfflags_t flags);
struct quark_tx_info_t {
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);
const char *ValueForKey(const mapentity_t *entity, const char *key);

View File

@ -27,6 +27,7 @@
#include <map>
#include <unordered_map>
#include <array>
#include <optional>
#include <assert.h>
#include <ctype.h>
@ -149,7 +150,7 @@ typedef struct mtexinfo_s {
int32_t miptex = 0;
surfflags_t flags = {};
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 {
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[1][3] += DotProduct( rotate_offset, vecs[1] );
mapface->texinfo = FindTexinfo(texInfoNew, texInfoNew.flags);
mapface->texinfo = FindTexinfo(texInfoNew);
}
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);
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"))
return CONTENTS_ORIGIN;
if (!Q_strcasecmp(texname, "hint"))
@ -864,7 +872,7 @@ Brush_GetContents(const mapbrush_t *mapbrush)
return CONTENTS_SKY;
}
//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 };
memset(&mt.vecs, 0, sizeof(mt.vecs));
return FindTexinfo(mt, mt.flags);
return FindTexinfo(mt);
}
/*

View File

@ -26,6 +26,7 @@
#include <list>
#include <utility>
#include <cassert>
#include <optional>
#include <ctype.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
FindMiptex(const char *name)
FindMiptex(const char *name, std::optional<extended_texinfo_t> &extended_info)
{
const char *pathsep;
int i;
@ -177,24 +205,59 @@ FindMiptex(const char *name)
pathsep = strrchr(name, '/');
if (pathsep)
name = pathsep + 1;
}
for (i = 0; i < map.nummiptex(); i++) {
if (!Q_strcasecmp(name, map.miptex.at(i).name.c_str()))
return i;
}
extended_info = extended_texinfo_t { };
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 */
if (options.target_version->game->id != GAME_QUAKE_II) {
/* Handle animating textures carefully */
if (name[0] == '+') {
AddAnimTex(name);
i = map.nummiptex();
}
} 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;
}
@ -256,7 +319,7 @@ Returns a global texinfo number
===============
*/
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 <.
// They should have been stripped out already in ValidateTextureProjection.
@ -295,9 +358,9 @@ normalize_color_format(vec3_t color)
}
}
static int
FindTexinfoEnt(const mtexinfo_t &texinfo, const mapentity_t *entity)
{
static surfflags_t
SurfFlagsForEntity(const mtexinfo_t &texinfo, const mapentity_t *entity)
{
surfflags_t flags {};
const char *texname = map.miptex.at(texinfo.miptex).name.c_str();
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;
if (IsSpecialName(texname))
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))
flags.extended |= TEX_EXFLAG_NOEXPAND;
@ -389,8 +459,8 @@ FindTexinfoEnt(const mtexinfo_t &texinfo, const mapentity_t *entity)
if (lightalpha != 0.0) {
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);
}
static extended_tx_info_t
static quark_tx_info_t
ParseExtendedTX(parser_t *parser)
{
extended_tx_info_t result;
quark_tx_info_t result;
if (ParseToken(parser, PARSE_COMMENT | PARSE_OPTIONAL)) {
if (!strncmp(parser->token, "//TX", 4)) {
@ -481,13 +551,14 @@ ParseExtendedTX(parser_t *parser)
} else {
// Parse extra Quake 2 surface info
if (ParseToken(parser, PARSE_OPTIONAL)) {
result.contents = atoi(parser->token);
}
if (ParseToken(parser, PARSE_OPTIONAL)) {
result.flags = atoi(parser->token);
}
if (ParseToken(parser, PARSE_OPTIONAL)) {
result.value = atoi(parser->token);
result.info = extended_texinfo_t { atoi(parser->token) };
if (ParseToken(parser, PARSE_OPTIONAL)) {
result.info->flags = atoi(parser->token);
}
if (ParseToken(parser, PARSE_OPTIONAL)) {
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));
extended_tx_info_t extinfo { };
quark_tx_info_t extinfo;
if (brush->format == brushformat_t::BRUSH_PRIMITIVES) {
ParseBrushPrimTX(parser, texMat);
@ -1372,9 +1443,6 @@ ParseTextureDef(parser_t *parser, mapface_t &mapface, const mapbrush_t *brush, m
// Read extra Q2 params
extinfo = ParseExtendedTX(parser);
mapface.contents = extinfo.contents;
mapface.flags = { extinfo.flags };
mapface.value = extinfo.value;
} else if (brush->format == brushformat_t::NORMAL) {
ParseToken(parser, PARSE_SAMELINE);
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
extinfo = ParseExtendedTX(parser);
mapface.contents = extinfo.contents;
mapface.flags = { extinfo.flags };
mapface.value = extinfo.value;
} else {
shift[0] = atof(parser->token);
ParseToken(parser, PARSE_SAMELINE);
@ -1410,13 +1475,15 @@ ParseTextureDef(parser_t *parser, mapface_t &mapface, const mapbrush_t *brush, m
} else {
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)
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
@ -1570,7 +1637,8 @@ ParseBrushFace(parser_t *parser, const mapbrush_t *brush, const mapentity_t *ent
ValidateTextureProjection(*face, &tx);
face->texinfo = FindTexinfoEnt(tx, entity);
tx.flags = SurfFlagsForEntity(tx, entity);
face->texinfo = FindTexinfo(tx);
return face;
}

View File

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