Fix operator<
Introduce gamedef, to reduce rewriting of data in bspversions fix name of needs_subdivision include value in texinfo, in prep for Q2
This commit is contained in:
parent
acc65953ce
commit
00efa6e67d
|
|
@ -22,34 +22,88 @@
|
||||||
#include <common/bspfile.hh>
|
#include <common/bspfile.hh>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
bool q1_surf_is_lightmapped(const surfflags_t &flags) {
|
struct gamedef_generic_t : public gamedef_t {
|
||||||
return !(flags.native & TEX_SPECIAL);
|
gamedef_generic_t()
|
||||||
}
|
{
|
||||||
|
id = GAME_UNKNOWN;
|
||||||
|
base_dir = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool q2_surf_is_lightmapped(const surfflags_t &flags) {
|
bool surf_is_lightmapped(const surfflags_t &flags) const {
|
||||||
return !(flags.native & (Q2_SURF_WARP | Q2_SURF_SKY | Q2_SURF_NODRAW)); // mxd. +Q2_SURF_NODRAW
|
throw std::bad_cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool q1_surf_needs_subdivision(const surfflags_t &flags) {
|
bool surf_is_subdivided(const surfflags_t &flags) const {
|
||||||
return flags.native & TEX_SPECIAL;
|
throw std::bad_cast();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool q2_surf_needs_subdivision(const surfflags_t &flags) {
|
template<gameid_t id>
|
||||||
return flags.native & (Q2_SURF_WARP | Q2_SURF_SKY);
|
struct gamedef_q1_like_t : public gamedef_t {
|
||||||
}
|
gamedef_q1_like_t()
|
||||||
|
{
|
||||||
|
this->id = id;
|
||||||
|
has_rgb_lightmap = false;
|
||||||
|
base_dir = "ID1";
|
||||||
|
}
|
||||||
|
|
||||||
/* game, colored lightmap, surf_is_lightmapped surf_needs_subdivision */
|
bool surf_is_lightmapped(const surfflags_t &flags) const {
|
||||||
const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP", GAME_UNKNOWN };
|
return !(flags.native & TEX_SPECIAL);
|
||||||
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 };
|
bool surf_is_subdivided(const surfflags_t &flags) const {
|
||||||
/* Hexen II doesn't use a separate version, but we can still use a separate tag/name for it */
|
return !(flags.native & TEX_SPECIAL);
|
||||||
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 };
|
struct gamedef_h2_t : public gamedef_q1_like_t<GAME_HEXEN_II> {
|
||||||
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 };
|
gamedef_h2_t()
|
||||||
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 };
|
{
|
||||||
|
base_dir = "DATA1";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gamedef_hl_t : public gamedef_q1_like_t<GAME_HALF_LIFE> {
|
||||||
|
gamedef_hl_t()
|
||||||
|
{
|
||||||
|
has_rgb_lightmap = true;
|
||||||
|
base_dir = "VALVE";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gamedef_q2_t : public gamedef_t {
|
||||||
|
gamedef_q2_t()
|
||||||
|
{
|
||||||
|
this->id = GAME_QUAKE_II;
|
||||||
|
has_rgb_lightmap = true;
|
||||||
|
base_dir = "BASEQ2";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool surf_is_lightmapped(const surfflags_t &flags) const {
|
||||||
|
return !(flags.native & (Q2_SURF_WARP | Q2_SURF_SKY | Q2_SURF_NODRAW)); // mxd. +Q2_SURF_NODRAW
|
||||||
|
}
|
||||||
|
|
||||||
|
bool surf_is_subdivided(const surfflags_t &flags) const {
|
||||||
|
return !(flags.native & (Q2_SURF_WARP | Q2_SURF_SKY));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gamedef_generic_t gamedef_generic;
|
||||||
|
const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP", &gamedef_generic };
|
||||||
|
static const gamedef_q1_like_t<GAME_QUAKE> gamedef_q1;
|
||||||
|
const bspversion_t bspver_q1 { BSPVERSION, NO_VERSION, "bsp29", "Quake BSP", &gamedef_q1 };
|
||||||
|
const bspversion_t bspver_bsp2 { BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2", &gamedef_q1 };
|
||||||
|
const bspversion_t bspver_bsp2rmq { BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ", &gamedef_q1 };
|
||||||
|
/* Hexen II doesn't use a separate version, but we can still use a separate tag/name for it */
|
||||||
|
static const gamedef_h2_t gamedef_h2;
|
||||||
|
const bspversion_t bspver_h2 { BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP", &gamedef_h2 };
|
||||||
|
const bspversion_t bspver_h2bsp2 { BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen II BSP2", &gamedef_h2 };
|
||||||
|
const bspversion_t bspver_h2bsp2rmq { BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq", "Hexen II BSP2-RMQ", &gamedef_h2 };
|
||||||
|
static const gamedef_hl_t gamedef_hl;
|
||||||
|
const bspversion_t bspver_hl { BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP", &gamedef_hl };
|
||||||
|
static const gamedef_q2_t gamedef_q2;
|
||||||
|
const bspversion_t bspver_q2 { Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP", &gamedef_q2 };
|
||||||
|
const bspversion_t bspver_qbism { Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP", &gamedef_q2 };
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
BSPVersionString(const bspversion_t *version)
|
BSPVersionString(const bspversion_t *version)
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ bool Face_IsLightmapped(const mbsp_t *bsp, const bsp2_dface_t *face)
|
||||||
if (texinfo == nullptr)
|
if (texinfo == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return bsp->loadversion->surf_is_lightmapped(texinfo->flags);
|
return bsp->loadversion->game->surf_is_lightmapped(texinfo->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float *GetSurfaceVertexPoint(const mbsp_t *bsp, const bsp2_dface_t *f, int v)
|
const float *GetSurfaceVertexPoint(const mbsp_t *bsp, const bsp2_dface_t *f, int v)
|
||||||
|
|
@ -215,7 +215,7 @@ TextureName_Contents(const char *texname)
|
||||||
bool //mxd
|
bool //mxd
|
||||||
ContentsOrSurfaceFlags_IsTranslucent(const mbsp_t *bsp, const int contents_or_surf_flags)
|
ContentsOrSurfaceFlags_IsTranslucent(const mbsp_t *bsp, const int contents_or_surf_flags)
|
||||||
{
|
{
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II)
|
if (bsp->loadversion->game->id == GAME_QUAKE_II)
|
||||||
return (contents_or_surf_flags & Q2_SURF_TRANSLUCENT) && ((contents_or_surf_flags & Q2_SURF_TRANSLUCENT) != Q2_SURF_TRANSLUCENT); // Don't count KMQ2 fence flags combo as translucent
|
return (contents_or_surf_flags & Q2_SURF_TRANSLUCENT) && ((contents_or_surf_flags & Q2_SURF_TRANSLUCENT) != Q2_SURF_TRANSLUCENT); // Don't count KMQ2 fence flags combo as translucent
|
||||||
else
|
else
|
||||||
return contents_or_surf_flags == CONTENTS_WATER || contents_or_surf_flags == CONTENTS_LAVA || contents_or_surf_flags == CONTENTS_SLIME;
|
return contents_or_surf_flags == CONTENTS_WATER || contents_or_surf_flags == CONTENTS_LAVA || contents_or_surf_flags == CONTENTS_SLIME;
|
||||||
|
|
@ -230,7 +230,7 @@ Face_IsTranslucent(const mbsp_t *bsp, const bsp2_dface_t *face)
|
||||||
int //mxd. Returns CONTENTS_ value for Q1, Q2_SURF_ bitflags for Q2...
|
int //mxd. Returns CONTENTS_ value for Q1, Q2_SURF_ bitflags for Q2...
|
||||||
Face_ContentsOrSurfaceFlags(const mbsp_t *bsp, const bsp2_dface_t *face)
|
Face_ContentsOrSurfaceFlags(const mbsp_t *bsp, const bsp2_dface_t *face)
|
||||||
{
|
{
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
const gtexinfo_t *info = Face_Texinfo(bsp, face);
|
const gtexinfo_t *info = Face_Texinfo(bsp, face);
|
||||||
return info->flags.native;
|
return info->flags.native;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -275,7 +275,7 @@ static bool Light_PointInSolid_r(const mbsp_t *bsp, const int nodenum, const vec
|
||||||
const mleaf_t *leaf = BSP_GetLeafFromNodeNum(bsp, nodenum);
|
const mleaf_t *leaf = BSP_GetLeafFromNodeNum(bsp, nodenum);
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
return leaf->contents & Q2_CONTENTS_SOLID;
|
return leaf->contents & Q2_CONTENTS_SOLID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#define __COMMON_BSPFILE_H__
|
#define __COMMON_BSPFILE_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <common/cmdlib.hh>
|
#include <common/cmdlib.hh>
|
||||||
#include <common/log.hh>
|
#include <common/log.hh>
|
||||||
|
|
@ -373,7 +374,7 @@ struct surfflags_t {
|
||||||
uint8_t minlight;
|
uint8_t minlight;
|
||||||
|
|
||||||
// red minlight colors for this face
|
// red minlight colors for this face
|
||||||
uint8_t minlight_color[3];
|
std::array<uint8_t, 3> minlight_color;
|
||||||
|
|
||||||
// if non zero, overrides _phong_angle for concave joints
|
// if non zero, overrides _phong_angle for concave joints
|
||||||
uint8_t phong_angle_concave;
|
uint8_t phong_angle_concave;
|
||||||
|
|
@ -980,13 +981,29 @@ typedef struct {
|
||||||
bspxentry_t *bspxentries;
|
bspxentry_t *bspxentries;
|
||||||
} bspdata_t;
|
} bspdata_t;
|
||||||
|
|
||||||
// native game ID target
|
// native game target ID
|
||||||
enum bspgame_t {
|
enum gameid_t {
|
||||||
GAME_UNKNOWN,
|
GAME_UNKNOWN,
|
||||||
GAME_QUAKE,
|
GAME_QUAKE,
|
||||||
GAME_HEXEN_II,
|
GAME_HEXEN_II,
|
||||||
GAME_HALF_LIFE,
|
GAME_HALF_LIFE,
|
||||||
GAME_QUAKE_II
|
GAME_QUAKE_II,
|
||||||
|
|
||||||
|
GAME_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Game definition, which contains data specific to
|
||||||
|
// the game a BSP version is being compiled for.
|
||||||
|
struct gamedef_t
|
||||||
|
{
|
||||||
|
gameid_t id;
|
||||||
|
|
||||||
|
bool has_rgb_lightmap;
|
||||||
|
|
||||||
|
const char *base_dir;
|
||||||
|
|
||||||
|
virtual bool surf_is_lightmapped(const surfflags_t &flags) const = 0;
|
||||||
|
virtual bool surf_is_subdivided(const surfflags_t &flags) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// BSP version struct & instances
|
// BSP version struct & instances
|
||||||
|
|
@ -1000,13 +1017,8 @@ 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;
|
||||||
/* game ID */
|
/* game ptr */
|
||||||
bspgame_t game;
|
const gamedef_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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const bspversion_t bspver_generic;
|
extern const bspversion_t bspver_generic;
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,7 @@ struct extended_tx_info_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
int FindMiptex(const char *name);
|
int FindMiptex(const char *name);
|
||||||
int FindTexinfo(mtexinfo_t *texinfo, surfflags_t flags); //FIXME: Make this take const texinfo
|
int FindTexinfo(const mtexinfo_t &texinfo, surfflags_t flags);
|
||||||
int FindTexinfoEnt(mtexinfo_t *texinfo, mapentity_t *entity); //FIXME: Make this take const 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);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
@ -141,14 +142,17 @@ enum {
|
||||||
#include <common/mathlib.hh>
|
#include <common/mathlib.hh>
|
||||||
#include <qbsp/winding.hh>
|
#include <qbsp/winding.hh>
|
||||||
|
|
||||||
|
using stvecs = std::array<std::array<float, 4>, 2>;
|
||||||
|
|
||||||
typedef struct mtexinfo_s {
|
typedef struct mtexinfo_s {
|
||||||
float vecs[2][4]; /* [s/t][xyz offset] */
|
stvecs vecs; /* [s/t][xyz offset] */
|
||||||
int32_t miptex;
|
int32_t miptex = 0;
|
||||||
surfflags_t flags;
|
surfflags_t flags = {};
|
||||||
int outputnum; // -1 until added to bsp
|
int32_t value = 0; // Q2-specific
|
||||||
|
int outputnum = -1; // -1 until added to bsp
|
||||||
|
|
||||||
constexpr auto as_tuple() const {
|
constexpr auto as_tuple() const {
|
||||||
return std::tie(vecs, miptex, flags);
|
return std::tie(vecs, miptex, flags, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator<(const mtexinfo_s &other) const {
|
constexpr bool operator<(const mtexinfo_s &other) const {
|
||||||
|
|
|
||||||
|
|
@ -1579,7 +1579,7 @@ static void MakeSurfaceLights(const mbsp_t *bsp)
|
||||||
|
|
||||||
for (int i = 0; i < bsp->numleafs; i++) {
|
for (int i = 0; i < bsp->numleafs; i++) {
|
||||||
const mleaf_t *leaf = bsp->dleafs + i;
|
const mleaf_t *leaf = bsp->dleafs + i;
|
||||||
const qboolean underwater = ((bsp->loadversion->game == GAME_QUAKE_II) ? (leaf->contents & Q2_CONTENTS_LIQUID) : leaf->contents != CONTENTS_EMPTY); //mxd
|
const qboolean underwater = ((bsp->loadversion->game->id == GAME_QUAKE_II) ? (leaf->contents & Q2_CONTENTS_LIQUID) : leaf->contents != CONTENTS_EMPTY); //mxd
|
||||||
|
|
||||||
for (int k = 0; k < leaf->nummarksurfaces; k++) {
|
for (int k = 0; k < leaf->nummarksurfaces; k++) {
|
||||||
const int facenum = bsp->dleaffaces[leaf->firstmarksurface + k];
|
const int facenum = bsp->dleaffaces[leaf->firstmarksurface + k];
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ void // WHO TOUCHED MY PALET?
|
||||||
LoadPalette(bspdata_t *bspdata)
|
LoadPalette(bspdata_t *bspdata)
|
||||||
{
|
{
|
||||||
// Load Quake 2 palette
|
// Load Quake 2 palette
|
||||||
if (bspdata->loadversion->game == GAME_QUAKE_II) {
|
if (bspdata->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
uint8_t *palette;
|
uint8_t *palette;
|
||||||
char path[1024];
|
char path[1024];
|
||||||
char colormap[] = "pics/colormap.pcx";
|
char colormap[] = "pics/colormap.pcx";
|
||||||
|
|
@ -66,7 +66,7 @@ LoadPalette(bspdata_t *bspdata)
|
||||||
for (int i = 0; i < 768; i++)
|
for (int i = 0; i < 768; i++)
|
||||||
thepalette[i] = palette[i];
|
thepalette[i] = palette[i];
|
||||||
|
|
||||||
} else if (bspdata->loadversion->game == GAME_HEXEN_II) {
|
} else if (bspdata->loadversion->game->id == GAME_HEXEN_II) {
|
||||||
// Copy Hexen 2 palette
|
// Copy Hexen 2 palette
|
||||||
for (int i = 0; i < 768; i++)
|
for (int i = 0; i < 768; i++)
|
||||||
thepalette[i] = hexen2palette[i];
|
thepalette[i] = hexen2palette[i];
|
||||||
|
|
@ -721,7 +721,7 @@ void // Expects correct palette and game/mod paths to be set
|
||||||
LoadOrConvertTextures(mbsp_t *bsp)
|
LoadOrConvertTextures(mbsp_t *bsp)
|
||||||
{
|
{
|
||||||
// Load or convert textures...
|
// Load or convert textures...
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II)
|
if (bsp->loadversion->game->id == GAME_QUAKE_II)
|
||||||
LoadTextures(bsp);
|
LoadTextures(bsp);
|
||||||
else if (bsp->texdatasize > 0)
|
else if (bsp->texdatasize > 0)
|
||||||
ConvertTextures(bsp);
|
ConvertTextures(bsp);
|
||||||
|
|
|
||||||
|
|
@ -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->game == GAME_QUAKE_II; //mxd
|
const qboolean isQuake2map = bsp->loadversion->game->id == 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 (bsp->loadversion->rgb_lightmap) {
|
if (bsp->loadversion->game->has_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);
|
||||||
|
|
@ -537,11 +537,7 @@ LoadExtendedTexinfoFlags(const char *sourcefilename, const mbsp_t *bsp)
|
||||||
static const char* //mxd
|
static const char* //mxd
|
||||||
GetBaseDirName(bspdata_t *bspdata)
|
GetBaseDirName(bspdata_t *bspdata)
|
||||||
{
|
{
|
||||||
if (bspdata->loadversion->game == GAME_QUAKE_II)
|
return bspdata->loadversion->game->base_dir;
|
||||||
return "BASEQ2";
|
|
||||||
if (bspdata->loadversion->game == GAME_HEXEN_II)
|
|
||||||
return "DATA1";
|
|
||||||
return "ID1";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//obj
|
//obj
|
||||||
|
|
@ -1194,7 +1190,7 @@ light_main(int argc, const char **argv)
|
||||||
ConvertBSPFormat(&bspdata, &bspver_generic);
|
ConvertBSPFormat(&bspdata, &bspver_generic);
|
||||||
|
|
||||||
//mxd. Use 1.0 rangescale as a default to better match with qrad3/arghrad
|
//mxd. Use 1.0 rangescale as a default to better match with qrad3/arghrad
|
||||||
if ((loadversion->game == GAME_QUAKE_II) && !cfg.rangescale.isChanged())
|
if ((loadversion->game->id == GAME_QUAKE_II) && !cfg.rangescale.isChanged())
|
||||||
{
|
{
|
||||||
const auto rs = new lockable_vec_t(cfg.rangescale.primaryName(), 1.0f, 0.0f, 100.0f);
|
const auto rs = new lockable_vec_t(cfg.rangescale.primaryName(), 1.0f, 0.0f, 100.0f);
|
||||||
cfg.rangescale = *rs; // Gross hacks to avoid displaying this in OptionsSummary...
|
cfg.rangescale = *rs; // Gross hacks to avoid displaying this in OptionsSummary...
|
||||||
|
|
@ -1234,7 +1230,7 @@ light_main(int argc, const char **argv)
|
||||||
|
|
||||||
if (!onlyents)
|
if (!onlyents)
|
||||||
{
|
{
|
||||||
if (!loadversion->rgb_lightmap) {
|
if (!loadversion->game->has_rgb_lightmap) {
|
||||||
CheckLitNeeded(cfg);
|
CheckLitNeeded(cfg);
|
||||||
}
|
}
|
||||||
SetupDirt(cfg);
|
SetupDirt(cfg);
|
||||||
|
|
|
||||||
|
|
@ -3081,7 +3081,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// skip lightmaps where all samples have brightness below 1
|
// skip lightmaps where all samples have brightness below 1
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) { // HACK: don't do this on Q2. seems if all styles are 0xff, the face is drawn fullbright instead of black (Q1)
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) { // HACK: don't do this on Q2. seems if all styles are 0xff, the face is drawn fullbright instead of black (Q1)
|
||||||
const float maxb = Lightmap_MaxBrightness(&lightmap, lightsurf);
|
const float maxb = Lightmap_MaxBrightness(&lightmap, lightsurf);
|
||||||
if (maxb < 1)
|
if (maxb < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3147,7 +3147,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
||||||
int lightofs;
|
int lightofs;
|
||||||
|
|
||||||
// Q2/HL native colored lightmaps
|
// Q2/HL native colored lightmaps
|
||||||
if (bsp->loadversion->rgb_lightmap) {
|
if (bsp->loadversion->game->has_rgb_lightmap) {
|
||||||
lightofs = lit - lit_filebase;
|
lightofs = lit - lit_filebase;
|
||||||
} else {
|
} else {
|
||||||
lightofs = out - filebase;
|
lightofs = out - filebase;
|
||||||
|
|
|
||||||
|
|
@ -716,7 +716,7 @@ TraceFaces (traceinfo_t *ti, int node, const vec3_t start, const vec3_t end)
|
||||||
|
|
||||||
// only solid and sky faces stop the trace.
|
// only solid and sky faces stop the trace.
|
||||||
bool issolid, issky; //mxd
|
bool issolid, issky; //mxd
|
||||||
if(bsp_static->loadversion->game == GAME_QUAKE_II) {
|
if(bsp_static->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
issolid = !(fi->content_or_surf_flags & Q2_SURF_TRANSLUCENT);
|
issolid = !(fi->content_or_surf_flags & Q2_SURF_TRANSLUCENT);
|
||||||
issky = (fi->content_or_surf_flags & Q2_SURF_SKY);
|
issky = (fi->content_or_surf_flags & Q2_SURF_SKY);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -353,7 +353,7 @@ Embree_FilterFuncN(const struct RTCFilterFunctionNArguments* args)
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
bool isFence, isGlass;
|
bool isFence, isGlass;
|
||||||
if(bsp_static->loadversion->game == GAME_QUAKE_II) {
|
if(bsp_static->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
const int surf_flags = Face_ContentsOrSurfaceFlags(bsp_static, face);
|
const int surf_flags = Face_ContentsOrSurfaceFlags(bsp_static, face);
|
||||||
isFence = ((surf_flags & Q2_SURF_TRANSLUCENT) == Q2_SURF_TRANSLUCENT); // KMQuake 2-specific. Use texture alpha chanel when both flags are set.
|
isFence = ((surf_flags & Q2_SURF_TRANSLUCENT) == Q2_SURF_TRANSLUCENT); // KMQuake 2-specific. Use texture alpha chanel when both flags are set.
|
||||||
isGlass = !isFence && (surf_flags & Q2_SURF_TRANSLUCENT);
|
isGlass = !isFence && (surf_flags & Q2_SURF_TRANSLUCENT);
|
||||||
|
|
@ -558,7 +558,7 @@ MakeFaces_r(const mbsp_t *bsp, const int nodenum, std::vector<plane_t> *planes,
|
||||||
const int leafnum = -nodenum - 1;
|
const int leafnum = -nodenum - 1;
|
||||||
const mleaf_t *leaf = &bsp->dleafs[leafnum];
|
const mleaf_t *leaf = &bsp->dleafs[leafnum];
|
||||||
|
|
||||||
if ((bsp->loadversion->game == GAME_QUAKE_II) ? (leaf->contents & Q2_CONTENTS_SOLID) : leaf->contents == CONTENTS_SOLID) {
|
if ((bsp->loadversion->game->id == GAME_QUAKE_II) ? (leaf->contents & Q2_CONTENTS_SOLID) : leaf->contents == CONTENTS_SOLID) {
|
||||||
std::vector<winding_t *> leaf_windings = Leaf_MakeFaces(bsp, leaf, *planes);
|
std::vector<winding_t *> leaf_windings = Leaf_MakeFaces(bsp, leaf, *planes);
|
||||||
for (winding_t *w : leaf_windings) {
|
for (winding_t *w : leaf_windings) {
|
||||||
result->push_back(w);
|
result->push_back(w);
|
||||||
|
|
@ -630,7 +630,7 @@ Embree_TraceInit(const mbsp_t *bsp)
|
||||||
|
|
||||||
const int contents_or_surf_flags = Face_ContentsOrSurfaceFlags(bsp, face); //mxd
|
const int contents_or_surf_flags = Face_ContentsOrSurfaceFlags(bsp, face); //mxd
|
||||||
const gtexinfo_t *texinfo = Face_Texinfo(bsp, face);
|
const gtexinfo_t *texinfo = Face_Texinfo(bsp, face);
|
||||||
const bool is_q2 = bsp->loadversion->game == GAME_QUAKE_II;
|
const bool is_q2 = bsp->loadversion->game->id == GAME_QUAKE_II;
|
||||||
|
|
||||||
//mxd. Skip NODRAW faces, but not SKY ones (Q2's sky01.wal has both flags set)
|
//mxd. Skip NODRAW faces, but not SKY ones (Q2's sky01.wal has both flags set)
|
||||||
if(is_q2 && (contents_or_surf_flags & Q2_SURF_NODRAW) && !(contents_or_surf_flags & Q2_SURF_SKY))
|
if(is_q2 && (contents_or_surf_flags & Q2_SURF_NODRAW) && !(contents_or_surf_flags & Q2_SURF_SKY))
|
||||||
|
|
|
||||||
|
|
@ -439,11 +439,11 @@ CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush,
|
||||||
// account for texture offset, from txqbsp-xt
|
// account for texture offset, from txqbsp-xt
|
||||||
if (options.fixRotateObjTexture) {
|
if (options.fixRotateObjTexture) {
|
||||||
const mtexinfo_t &texinfo = map.mtexinfos.at(mapface->texinfo);
|
const mtexinfo_t &texinfo = map.mtexinfos.at(mapface->texinfo);
|
||||||
mtexinfo_t texInfoNew;
|
mtexinfo_t texInfoNew = texinfo;
|
||||||
|
texInfoNew.outputnum = -1;
|
||||||
vec3_t vecs[2];
|
vec3_t vecs[2];
|
||||||
int k, l;
|
int k, l;
|
||||||
|
|
||||||
memcpy(&texInfoNew, &texinfo, sizeof(texInfoNew));
|
|
||||||
for (k=0; k<2; k++) {
|
for (k=0; k<2; k++) {
|
||||||
for (l=0; l<3; l++) {
|
for (l=0; l<3; l++) {
|
||||||
vecs[k][l] = texinfo.vecs[k][l];
|
vecs[k][l] = texinfo.vecs[k][l];
|
||||||
|
|
@ -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, texInfoNew.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy(mapface->plane.normal, plane.normal);
|
VectorCopy(mapface->plane.normal, plane.normal);
|
||||||
|
|
@ -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->game != GAME_HEXEN_II; // never do this in Hexen 2
|
&& options.target_version->game->id != 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->game == GAME_HEXEN_II)
|
else if (options.target_version->game->id == 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} };
|
||||||
|
|
|
||||||
|
|
@ -53,16 +53,13 @@ MakeSkipTexinfo()
|
||||||
// FindMiptex, FindTexinfo not threadsafe
|
// FindMiptex, FindTexinfo not threadsafe
|
||||||
std::unique_lock<std::mutex> lck { csgfaces_lock };
|
std::unique_lock<std::mutex> lck { csgfaces_lock };
|
||||||
|
|
||||||
int texinfo;
|
mtexinfo_t mt { };
|
||||||
mtexinfo_t mt;
|
|
||||||
|
|
||||||
mt.miptex = FindMiptex("skip");
|
mt.miptex = FindMiptex("skip");
|
||||||
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));
|
||||||
|
|
||||||
texinfo = FindTexinfo(&mt, mt.flags);
|
return FindTexinfo(mt, mt.flags);
|
||||||
|
|
||||||
return texinfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
55
qbsp/map.cc
55
qbsp/map.cc
|
|
@ -112,7 +112,7 @@ public:
|
||||||
static texdef_valve_t TexDef_BSPToValve(const float in_vecs[2][4]);
|
static texdef_valve_t TexDef_BSPToValve(const float in_vecs[2][4]);
|
||||||
static qvec2f projectToAxisPlane(const vec3_t snapped_normal, qvec3f point);
|
static qvec2f projectToAxisPlane(const vec3_t snapped_normal, qvec3f point);
|
||||||
static texdef_quake_ed_noshift_t Reverse_QuakeEd(qmat2x2f M, const qbsp_plane_t *plane, bool preserveX);
|
static texdef_quake_ed_noshift_t Reverse_QuakeEd(qmat2x2f M, const qbsp_plane_t *plane, bool preserveX);
|
||||||
static void SetTexinfo_QuakeEd_New(const qbsp_plane_t *plane, const vec_t shift[2], vec_t rotate, const vec_t scale[2], float out_vecs[2][4]);
|
static void SetTexinfo_QuakeEd_New(const qbsp_plane_t *plane, const vec_t shift[2], vec_t rotate, const vec_t scale[2], stvecs &out_vecs);
|
||||||
static void TestExpandBrushes(const mapentity_t *src);
|
static void TestExpandBrushes(const mapentity_t *src);
|
||||||
|
|
||||||
const mapface_t &mapbrush_t::face(int i) const {
|
const mapface_t &mapbrush_t::face(int i) const {
|
||||||
|
|
@ -172,7 +172,7 @@ FindMiptex(const char *name)
|
||||||
const char *pathsep;
|
const char *pathsep;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (options.target_version->game != GAME_QUAKE_II) {
|
if (options.target_version->game->id != 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,7 +185,7 @@ FindMiptex(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle animating textures carefully */
|
/* Handle animating textures carefully */
|
||||||
if (options.target_version->game != GAME_QUAKE_II) {
|
if (options.target_version->game->id != GAME_QUAKE_II) {
|
||||||
if (name[0] == '+') {
|
if (name[0] == '+') {
|
||||||
AddAnimTex(name);
|
AddAnimTex(name);
|
||||||
i = map.nummiptex();
|
i = map.nummiptex();
|
||||||
|
|
@ -256,33 +256,29 @@ Returns a global texinfo number
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
FindTexinfo(mtexinfo_t *texinfo, surfflags_t flags)
|
FindTexinfo(const mtexinfo_t &texinfo, surfflags_t flags)
|
||||||
{
|
{
|
||||||
/* Set the texture flags */
|
|
||||||
texinfo->flags = flags;
|
|
||||||
texinfo->outputnum = -1;
|
|
||||||
|
|
||||||
// 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.
|
||||||
for (int i=0;i<2;i++) {
|
for (int i=0;i<2;i++) {
|
||||||
for (int j=0;j<4;j++) {
|
for (int j=0;j<4;j++) {
|
||||||
Q_assert(!std::isnan(texinfo->vecs[i][j]));
|
Q_assert(!std::isnan(texinfo.vecs[i][j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for an exact match in the reverse lookup
|
// check for an exact match in the reverse lookup
|
||||||
const auto it = map.mtexinfo_lookup.find(*texinfo);
|
const auto it = map.mtexinfo_lookup.find(texinfo);
|
||||||
if (it != map.mtexinfo_lookup.end()) {
|
if (it != map.mtexinfo_lookup.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new texinfo at the end of the array */
|
/* Allocate a new texinfo at the end of the array */
|
||||||
const int num_texinfo = static_cast<int>(map.mtexinfos.size());
|
const int num_texinfo = static_cast<int>(map.mtexinfos.size());
|
||||||
map.mtexinfos.push_back(*texinfo);
|
map.mtexinfos.push_back(texinfo);
|
||||||
map.mtexinfo_lookup[*texinfo] = num_texinfo;
|
map.mtexinfo_lookup[texinfo] = num_texinfo;
|
||||||
|
|
||||||
// catch broken < implementations in mtexinfo_t
|
// catch broken < implementations in mtexinfo_t
|
||||||
assert(map.mtexinfo_lookup.find(*texinfo) != map.mtexinfo_lookup.end());
|
assert(map.mtexinfo_lookup.find(texinfo) != map.mtexinfo_lookup.end());
|
||||||
|
|
||||||
return num_texinfo;
|
return num_texinfo;
|
||||||
}
|
}
|
||||||
|
|
@ -299,14 +295,14 @@ normalize_color_format(vec3_t color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
FindTexinfoEnt(mtexinfo_t *texinfo, const mapentity_t *entity)
|
FindTexinfoEnt(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"));
|
||||||
// These flags are pulled from surf flags in Q2.
|
// These flags are pulled from surf flags in Q2.
|
||||||
if (options.target_version->game != GAME_QUAKE_II) {
|
if (options.target_version->game->id != 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))
|
||||||
|
|
@ -422,7 +418,7 @@ ParseEpair(parser_t *parser, mapentity_t *entity)
|
||||||
// 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 in Q2.
|
// one info_player_start per targetname in Q2.
|
||||||
if (options.target_version->game != GAME_QUAKE_II && (rgfStartSpots & info_player_start))
|
if (options.target_version->game->id != 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")) {
|
||||||
|
|
@ -498,7 +494,7 @@ ParseExtendedTX(parser_t *parser)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qmat4x4f texVecsTo4x4Matrix(const qbsp_plane_t &faceplane, const float in_vecs[2][4])
|
static qmat4x4f texVecsTo4x4Matrix(const qbsp_plane_t &faceplane, const stvecs &in_vecs)
|
||||||
{
|
{
|
||||||
// [s]
|
// [s]
|
||||||
// T * vec = [t]
|
// T * vec = [t]
|
||||||
|
|
@ -545,7 +541,7 @@ static float extractRotation(qmat2x2f m) {
|
||||||
|
|
||||||
static qvec2f evalTexDefAtPoint(const texdef_quake_ed_t &texdef, const qbsp_plane_t *faceplane, const qvec3f point)
|
static qvec2f evalTexDefAtPoint(const texdef_quake_ed_t &texdef, const qbsp_plane_t *faceplane, const qvec3f point)
|
||||||
{
|
{
|
||||||
float temp[2][4];
|
stvecs temp;
|
||||||
SetTexinfo_QuakeEd_New(faceplane, texdef.shift, texdef.rotate, texdef.scale, temp);
|
SetTexinfo_QuakeEd_New(faceplane, texdef.shift, texdef.rotate, texdef.scale, temp);
|
||||||
|
|
||||||
const qmat4x4f worldToTexSpace_res = texVecsTo4x4Matrix(*faceplane, temp);
|
const qmat4x4f worldToTexSpace_res = texVecsTo4x4Matrix(*faceplane, temp);
|
||||||
|
|
@ -608,7 +604,7 @@ qvec2f normalizeShift(const texture_t *texture, const qvec2f &in)
|
||||||
|
|
||||||
/// `texture` is optional. If given, the "shift" values can be normalized
|
/// `texture` is optional. If given, the "shift" values can be normalized
|
||||||
static texdef_quake_ed_t
|
static texdef_quake_ed_t
|
||||||
TexDef_BSPToQuakeEd(const qbsp_plane_t &faceplane, const texture_t *texture, const float in_vecs[2][4], const vec3_t facepoints[3])
|
TexDef_BSPToQuakeEd(const qbsp_plane_t &faceplane, const texture_t *texture, const stvecs &in_vecs, const vec3_t facepoints[3])
|
||||||
{
|
{
|
||||||
// First get the un-rotated, un-scaled unit texture vecs (based on the face plane).
|
// First get the un-rotated, un-scaled unit texture vecs (based on the face plane).
|
||||||
vec3_t snapped_normal;
|
vec3_t snapped_normal;
|
||||||
|
|
@ -892,7 +888,7 @@ Reverse_QuakeEd(qmat2x2f M, const qbsp_plane_t *plane, bool preserveX)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SetTexinfo_QuakeEd_New(const qbsp_plane_t *plane, const vec_t shift[2], vec_t rotate, const vec_t scale[2], float out_vecs[2][4])
|
SetTexinfo_QuakeEd_New(const qbsp_plane_t *plane, const vec_t shift[2], vec_t rotate, const vec_t scale[2], stvecs &out_vecs)
|
||||||
{
|
{
|
||||||
vec_t sanitized_scale[2];
|
vec_t sanitized_scale[2];
|
||||||
for (int i=0; i<2; i++) {
|
for (int i=0; i<2; i++) {
|
||||||
|
|
@ -1011,7 +1007,7 @@ SetTexinfo_QuakeEd(const qbsp_plane_t *plane, const vec3_t planepts[3], const ve
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
// Self-test of SetTexinfo_QuakeEd_New
|
// Self-test of SetTexinfo_QuakeEd_New
|
||||||
float check[2][4];
|
stvecs check;
|
||||||
SetTexinfo_QuakeEd_New(plane, shift, rotate, scale, check);
|
SetTexinfo_QuakeEd_New(plane, shift, rotate, scale, check);
|
||||||
for (int i=0; i<2; i++) {
|
for (int i=0; i<2; i++) {
|
||||||
for (int j=0; j<4; j++) {
|
for (int j=0; j<4; j++) {
|
||||||
|
|
@ -1174,7 +1170,7 @@ static void ComputeAxisBase( const vec3_t normal_unsanitized, vec3_t texX, vec3_
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SetTexinfo_BrushPrimitives(const vec3_t texMat[2], const vec3_t faceNormal, int texWidth, int texHeight, float vecs[2][4])
|
SetTexinfo_BrushPrimitives(const vec3_t texMat[2], const vec3_t faceNormal, int texWidth, int texHeight, stvecs &vecs)
|
||||||
{
|
{
|
||||||
vec3_t texX, texY;
|
vec3_t texX, texY;
|
||||||
|
|
||||||
|
|
@ -1214,7 +1210,7 @@ SetTexinfo_BrushPrimitives(const vec3_t texMat[2], const vec3_t faceNormal, int
|
||||||
vecs[1][3] = texHeight * texMat[1][2];
|
vecs[1][3] = texHeight * texMat[1][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSP_GetSTCoordsForPoint(const vec_t *point, const int texSize[2], const float in_vecs[2][4], vec_t *st_out)
|
static void BSP_GetSTCoordsForPoint(const vec_t *point, const int texSize[2], const stvecs &in_vecs, vec_t *st_out)
|
||||||
{
|
{
|
||||||
for (int i=0; i<2; i++) {
|
for (int i=0; i<2; i++) {
|
||||||
st_out[i] = (point[0] * in_vecs[i][0]
|
st_out[i] = (point[0] * in_vecs[i][0]
|
||||||
|
|
@ -1226,7 +1222,7 @@ static void BSP_GetSTCoordsForPoint(const vec_t *point, const int texSize[2], co
|
||||||
|
|
||||||
// From FaceToBrushPrimitFace in GtkRadiant
|
// From FaceToBrushPrimitFace in GtkRadiant
|
||||||
static texdef_brush_primitives_t
|
static texdef_brush_primitives_t
|
||||||
TexDef_BSPToBrushPrimitives(const qbsp_plane_t plane, const int texSize[2], const float in_vecs[2][4])
|
TexDef_BSPToBrushPrimitives(const qbsp_plane_t plane, const int texSize[2], const stvecs &in_vecs)
|
||||||
{
|
{
|
||||||
vec3_t texX, texY;
|
vec3_t texX, texY;
|
||||||
ComputeAxisBase( plane.normal, texX, texY );
|
ComputeAxisBase( plane.normal, texX, texY );
|
||||||
|
|
@ -1474,6 +1470,7 @@ void mapface_t::set_texvecs(const std::array<qvec4f, 2> &vecs)
|
||||||
{
|
{
|
||||||
// start with a copy of the current texinfo structure
|
// start with a copy of the current texinfo structure
|
||||||
mtexinfo_t texInfoNew = map.mtexinfos.at(this->texinfo);
|
mtexinfo_t texInfoNew = map.mtexinfos.at(this->texinfo);
|
||||||
|
texInfoNew.outputnum = -1;
|
||||||
|
|
||||||
// update vecs
|
// update vecs
|
||||||
for (int i=0; i<2; i++) {
|
for (int i=0; i<2; i++) {
|
||||||
|
|
@ -1482,7 +1479,7 @@ void mapface_t::set_texvecs(const std::array<qvec4f, 2> &vecs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->texinfo = FindTexinfo( &texInfoNew, texInfoNew.flags );
|
this->texinfo = FindTexinfo(texInfoNew, texInfoNew.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1573,7 +1570,7 @@ ParseBrushFace(parser_t *parser, const mapbrush_t *brush, const mapentity_t *ent
|
||||||
|
|
||||||
ValidateTextureProjection(*face, &tx);
|
ValidateTextureProjection(*face, &tx);
|
||||||
|
|
||||||
face->texinfo = FindTexinfoEnt(&tx, entity);
|
face->texinfo = FindTexinfoEnt(tx, entity);
|
||||||
|
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
@ -1972,7 +1969,7 @@ LoadMapFile(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static texdef_valve_t
|
static texdef_valve_t
|
||||||
TexDef_BSPToValve(const float in_vecs[2][4])
|
TexDef_BSPToValve(const stvecs &in_vecs)
|
||||||
{
|
{
|
||||||
texdef_valve_t res;
|
texdef_valve_t res;
|
||||||
|
|
||||||
|
|
|
||||||
10
qbsp/qbsp.cc
10
qbsp/qbsp.cc
|
|
@ -575,7 +575,7 @@ CreateHulls(void)
|
||||||
|
|
||||||
if (options.target_version == &bspver_hl)
|
if (options.target_version == &bspver_hl)
|
||||||
CreateSingleHull(3);
|
CreateSingleHull(3);
|
||||||
else if (options.target_version->game == GAME_HEXEN_II)
|
else if (options.target_version->game->id == 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);
|
||||||
|
|
@ -622,11 +622,7 @@ EnsureTexturesLoaded()
|
||||||
static const char* //mxd
|
static const char* //mxd
|
||||||
GetBaseDirName(const bspversion_t *bspver)
|
GetBaseDirName(const bspversion_t *bspver)
|
||||||
{
|
{
|
||||||
if (bspver->game == GAME_QUAKE_II)
|
return bspver->game->base_dir;
|
||||||
return "BASEQ2";
|
|
||||||
if (bspver->game == GAME_HEXEN_II)
|
|
||||||
return "DATA1";
|
|
||||||
return "ID1";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -977,7 +973,7 @@ ParseOptions(char *szOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// force specific flags for Q2
|
// force specific flags for Q2
|
||||||
if (options.target_version->game == GAME_QUAKE_II) {
|
if (options.target_version->game->id == GAME_QUAKE_II) {
|
||||||
options.fNoclip = true;
|
options.fNoclip = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ SubdivideFace(face_t *f, face_t **prevptr)
|
||||||
|
|
||||||
/* special (non-surface cached) faces don't need subdivision */
|
/* special (non-surface cached) faces don't need subdivision */
|
||||||
tex = &map.mtexinfos.at(f->texinfo);
|
tex = &map.mtexinfos.at(f->texinfo);
|
||||||
// FIXME: Q2
|
|
||||||
if (tex->flags.extended & (TEX_EXFLAG_SKIP | TEX_EXFLAG_HINT) ||
|
if (tex->flags.extended & (TEX_EXFLAG_SKIP | TEX_EXFLAG_HINT) ||
|
||||||
options.target_version->surf_needs_subdivision(tex->flags))
|
!options.target_version->game->surf_is_subdivided(tex->flags))
|
||||||
return;
|
return;
|
||||||
//subdivision is pretty much pointless other than because of lightmap block limits
|
//subdivision is pretty much pointless other than because of lightmap block limits
|
||||||
//one lightmap block will always be added at the end, for smooth interpolation
|
//one lightmap block will always be added at the end, for smooth interpolation
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ static void
|
||||||
AssertVanillaContentType(int content)
|
AssertVanillaContentType(int content)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
if (options.target_version->game == GAME_QUAKE_II) {
|
if (options.target_version->game->id == GAME_QUAKE_II) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ RemapContentsForExport(int content)
|
||||||
content = RemapContentsForExport_(content);
|
content = RemapContentsForExport_(content);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
if (options.target_version->game == GAME_QUAKE_II) {
|
if (options.target_version->game->id == GAME_QUAKE_II) {
|
||||||
switch (content) {
|
switch (content) {
|
||||||
case CONTENTS_EMPTY:
|
case CONTENTS_EMPTY:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -124,7 +124,7 @@ int
|
||||||
ExportMapTexinfo(int texinfonum)
|
ExportMapTexinfo(int texinfonum)
|
||||||
{
|
{
|
||||||
mtexinfo_t *src = &map.mtexinfos.at(texinfonum);
|
mtexinfo_t *src = &map.mtexinfos.at(texinfonum);
|
||||||
if (src->outputnum != PLANENUM_LEAF)
|
if (src->outputnum != -1)
|
||||||
return src->outputnum;
|
return src->outputnum;
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -292,7 +292,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->game != GAME_QUAKE_II && node->children[i]->contents == CONTENTS_SOLID)
|
if (options.target_version->game->id != 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.size());
|
int nextLeafIndex = static_cast<int>(map.exported_leafs.size());
|
||||||
|
|
|
||||||
16
vis/vis.cc
16
vis/vis.cc
|
|
@ -571,7 +571,7 @@ LeafFlow(int leafnum, mleaf_t *dleaf, const mbsp_t *bsp)
|
||||||
/*
|
/*
|
||||||
* flow through all portals, collecting visible bits
|
* flow through all portals, collecting visible bits
|
||||||
*/
|
*/
|
||||||
outbuffer = (bsp->loadversion->game == GAME_QUAKE_II ? uncompressed_q2 : uncompressed) + leafnum * leafbytes;
|
outbuffer = (bsp->loadversion->game->id == GAME_QUAKE_II ? uncompressed_q2 : uncompressed) + leafnum * leafbytes;
|
||||||
leaf = &leafs[leafnum];
|
leaf = &leafs[leafnum];
|
||||||
for (i = 0; i < leaf->numportals; i++) {
|
for (i = 0; i < leaf->numportals; i++) {
|
||||||
p = leaf->portals[i];
|
p = leaf->portals[i];
|
||||||
|
|
@ -653,7 +653,7 @@ ClusterFlow(int clusternum, leafbits_t *buffer, const mbsp_t *bsp)
|
||||||
*/
|
*/
|
||||||
numvis = 0;
|
numvis = 0;
|
||||||
|
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
outbuffer = uncompressed_q2 + clusternum * leafbytes;
|
outbuffer = uncompressed_q2 + clusternum * leafbytes;
|
||||||
for (i = 0; i < portalleafs; i++) {
|
for (i = 0; i < portalleafs; i++) {
|
||||||
if (TestLeafBit(buffer, i)) {
|
if (TestLeafBit(buffer, i)) {
|
||||||
|
|
@ -688,7 +688,7 @@ ClusterFlow(int clusternum, leafbits_t *buffer, const mbsp_t *bsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate for worst case where RLE might grow the data (unlikely) */
|
/* Allocate for worst case where RLE might grow the data (unlikely) */
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
compressed = static_cast<uint8_t *>(malloc(portalleafs * 2 / 8));
|
compressed = static_cast<uint8_t *>(malloc(portalleafs * 2 / 8));
|
||||||
len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed);
|
len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1061,7 +1061,7 @@ LoadPortals(char *name, mbsp_t *bsp)
|
||||||
if (count != 2)
|
if (count != 2)
|
||||||
Error("%s: unable to parse %s HEADER\n", __func__, PORTALFILE);
|
Error("%s: unable to parse %s HEADER\n", __func__, PORTALFILE);
|
||||||
|
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
portalleafs_real = bsp->numleafs;
|
portalleafs_real = bsp->numleafs;
|
||||||
logprint("%6d leafs\n", portalleafs_real);
|
logprint("%6d leafs\n", portalleafs_real);
|
||||||
logprint("%6d clusters\n", portalleafs);
|
logprint("%6d clusters\n", portalleafs);
|
||||||
|
|
@ -1101,7 +1101,7 @@ LoadPortals(char *name, mbsp_t *bsp)
|
||||||
leafs = static_cast<leaf_t *>(malloc(portalleafs * sizeof(leaf_t)));
|
leafs = static_cast<leaf_t *>(malloc(portalleafs * sizeof(leaf_t)));
|
||||||
memset(leafs, 0, portalleafs * sizeof(leaf_t));
|
memset(leafs, 0, portalleafs * sizeof(leaf_t));
|
||||||
|
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
originalvismapsize = portalleafs * ((portalleafs + 7) / 8);
|
originalvismapsize = portalleafs * ((portalleafs + 7) / 8);
|
||||||
} else {
|
} else {
|
||||||
originalvismapsize = portalleafs_real * ((portalleafs_real + 7) / 8);
|
originalvismapsize = portalleafs_real * ((portalleafs_real + 7) / 8);
|
||||||
|
|
@ -1180,7 +1180,7 @@ LoadPortals(char *name, mbsp_t *bsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the cluster expansion map if needed */
|
/* Load the cluster expansion map if needed */
|
||||||
if (bsp->loadversion->game == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
clustermap = static_cast<int *>(malloc(portalleafs_real * sizeof(int)));
|
clustermap = static_cast<int *>(malloc(portalleafs_real * sizeof(int)));
|
||||||
|
|
||||||
for (int32_t i = 0; i < bsp->numleafs; i++) {
|
for (int32_t i = 0; i < bsp->numleafs; i++) {
|
||||||
|
|
@ -1333,7 +1333,7 @@ main(int argc, char **argv)
|
||||||
StripExtension(statetmpfile);
|
StripExtension(statetmpfile);
|
||||||
DefaultExtension(statetmpfile, ".vi0");
|
DefaultExtension(statetmpfile, ".vi0");
|
||||||
|
|
||||||
if (bsp->loadversion->game != GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id != GAME_QUAKE_II) {
|
||||||
uncompressed = static_cast<uint8_t *>(calloc(portalleafs, leafbytes_real));
|
uncompressed = static_cast<uint8_t *>(calloc(portalleafs, leafbytes_real));
|
||||||
} else {
|
} else {
|
||||||
uncompressed_q2 = static_cast<uint8_t *>(calloc(portalleafs, leafbytes));
|
uncompressed_q2 = static_cast<uint8_t *>(calloc(portalleafs, leafbytes));
|
||||||
|
|
@ -1351,7 +1351,7 @@ main(int argc, char **argv)
|
||||||
bsp->visdatasize, originalvismapsize);
|
bsp->visdatasize, originalvismapsize);
|
||||||
|
|
||||||
// no ambient sounds for Q2
|
// no ambient sounds for Q2
|
||||||
if (bsp->loadversion->game != GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id != GAME_QUAKE_II) {
|
||||||
CalcAmbientSounds(bsp);
|
CalcAmbientSounds(bsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue