Tighten processing of WALL_IS_DOORWAY flags
This commit is contained in:
parent
3573d680ef
commit
02e2e77ee6
|
@ -112,7 +112,8 @@ int check_lsegments_validity(void);
|
|||
// set to WID_FLY_FLAG to see if a robot could fly from one to the other.
|
||||
// Search up to a maximum depth of max_depth.
|
||||
// Return the distance.
|
||||
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, int wid_flag);
|
||||
struct WALL_IS_DOORWAY_mask_t;
|
||||
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, WALL_IS_DOORWAY_mask_t wid_flag);
|
||||
|
||||
//create a matrix that describes the orientation of the given segment
|
||||
extern void extract_orient_from_segment(vms_matrix *m,segment *seg);
|
||||
|
|
|
@ -100,22 +100,93 @@ struct vobjptridx_t;
|
|||
#define MAX_CLIP_FRAMES 50
|
||||
#endif
|
||||
|
||||
template <unsigned value>
|
||||
struct WALL_IS_DOORWAY_FLAG
|
||||
{
|
||||
constexpr operator unsigned() const { return value; }
|
||||
template <unsigned F2>
|
||||
constexpr WALL_IS_DOORWAY_FLAG<value | F2> operator|(WALL_IS_DOORWAY_FLAG<F2>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned F>
|
||||
struct WALL_IS_DOORWAY_sresult_t
|
||||
{
|
||||
};
|
||||
|
||||
template <unsigned F>
|
||||
static inline constexpr WALL_IS_DOORWAY_sresult_t<F> WALL_IS_DOORWAY_sresult(WALL_IS_DOORWAY_FLAG<F>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
struct WALL_IS_DOORWAY_mask_t
|
||||
{
|
||||
unsigned value;
|
||||
template <unsigned F>
|
||||
constexpr WALL_IS_DOORWAY_mask_t(WALL_IS_DOORWAY_FLAG<F>) :
|
||||
value(F)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct WALL_IS_DOORWAY_result_t
|
||||
{
|
||||
unsigned value;
|
||||
template <unsigned F>
|
||||
constexpr WALL_IS_DOORWAY_result_t(WALL_IS_DOORWAY_sresult_t<F>) :
|
||||
value(F)
|
||||
{
|
||||
}
|
||||
template <unsigned F>
|
||||
unsigned operator&(WALL_IS_DOORWAY_FLAG<F>) const
|
||||
{
|
||||
return value & F;
|
||||
}
|
||||
template <unsigned F>
|
||||
WALL_IS_DOORWAY_result_t operator|=(WALL_IS_DOORWAY_FLAG<F>)
|
||||
{
|
||||
value |= F;
|
||||
return *this;
|
||||
}
|
||||
template <unsigned F>
|
||||
bool operator==(WALL_IS_DOORWAY_sresult_t<F>) const
|
||||
{
|
||||
return value == F;
|
||||
}
|
||||
bool operator&(WALL_IS_DOORWAY_mask_t m) const
|
||||
{
|
||||
return value & m.value;
|
||||
}
|
||||
bool operator==(WALL_IS_DOORWAY_result_t) const = delete;
|
||||
template <typename T>
|
||||
bool operator!=(const T &t) const
|
||||
{
|
||||
return !(*this == t);
|
||||
}
|
||||
};
|
||||
|
||||
// WALL_IS_DOORWAY flags.
|
||||
static const unsigned WID_FLY_FLAG = 1;
|
||||
static const unsigned WID_RENDER_FLAG = 2;
|
||||
static const unsigned WID_RENDPAST_FLAG = 4;
|
||||
static const unsigned WID_EXTERNAL_FLAG = 8;
|
||||
static const WALL_IS_DOORWAY_FLAG<1> WID_FLY_FLAG;
|
||||
static const WALL_IS_DOORWAY_FLAG<2> WID_RENDER_FLAG;
|
||||
static const WALL_IS_DOORWAY_FLAG<4> WID_RENDPAST_FLAG;
|
||||
static const WALL_IS_DOORWAY_FLAG<8> WID_EXTERNAL_FLAG;
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
static const unsigned WID_CLOAKED_FLAG = 16;
|
||||
static const WALL_IS_DOORWAY_FLAG<16> WID_CLOAKED_FLAG;
|
||||
#endif
|
||||
|
||||
// WALL_IS_DOORWAY return values F/R/RP
|
||||
static const unsigned WID_WALL = WID_RENDER_FLAG; // 0/1/0 wall
|
||||
static const unsigned WID_TRANSPARENT_WALL = WID_RENDER_FLAG | WID_RENDPAST_FLAG; // 0/1/1 transparent wall
|
||||
static const unsigned WID_ILLUSORY_WALL = WID_FLY_FLAG | WID_RENDPAST_FLAG; // 1/1/0 illusory wall
|
||||
static const unsigned WID_TRANSILLUSORY_WALL = WID_FLY_FLAG | WID_RENDER_FLAG | WID_RENDPAST_FLAG; // 1/1/1 transparent illusory wall
|
||||
static const unsigned WID_NO_WALL = WID_FLY_FLAG | WID_RENDPAST_FLAG; // 1/0/1 no wall, can fly through
|
||||
static const unsigned WID_EXTERNAL = WID_EXTERNAL_FLAG; // 0/0/0/1 don't see it, dont fly through it
|
||||
static const auto WID_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG); // 0/1/0 wall
|
||||
static const auto WID_TRANSPARENT_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG | WID_RENDPAST_FLAG); // 0/1/1 transparent wall
|
||||
static const auto WID_ILLUSORY_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDER_FLAG); // 1/1/0 illusory wall
|
||||
static const auto WID_TRANSILLUSORY_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDER_FLAG | WID_RENDPAST_FLAG); // 1/1/1 transparent illusory wall
|
||||
static const auto WID_NO_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDPAST_FLAG); // 1/0/1 no wall, can fly through
|
||||
static const auto WID_EXTERNAL = WALL_IS_DOORWAY_sresult(WID_EXTERNAL_FLAG); // 0/0/0/1 don't see it, dont fly through it
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
static const auto WID_CLOAKED_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG | WID_RENDPAST_FLAG | WID_CLOAKED_FLAG);
|
||||
#endif
|
||||
|
||||
#define MAX_STUCK_OBJECTS 32
|
||||
|
||||
|
@ -219,8 +290,6 @@ struct wclip : public prohibit_void_ptr<wclip>
|
|||
|
||||
extern const char Wall_names[7][10];
|
||||
|
||||
//#define WALL_IS_DOORWAY(seg,side) wall_is_doorway(seg, side)
|
||||
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
#define MAX_CLOAKING_WALLS 10
|
||||
extern array<cloaking_wall, MAX_CLOAKING_WALLS> CloakingWalls;
|
||||
|
@ -251,9 +320,9 @@ struct wclip;
|
|||
extern void wall_init();
|
||||
|
||||
// Automatically checks if a there is a doorway (i.e. can fly through)
|
||||
extern int wall_is_doorway ( segment *seg, int side );
|
||||
WALL_IS_DOORWAY_result_t wall_is_doorway (segment *seg, int side);
|
||||
|
||||
static inline int WALL_IS_DOORWAY(segment *seg, int side)
|
||||
static inline WALL_IS_DOORWAY_result_t WALL_IS_DOORWAY(segment *seg, int side)
|
||||
{
|
||||
if (seg->children[side] == segment_none)
|
||||
return WID_WALL;
|
||||
|
|
|
@ -92,13 +92,11 @@ static void add_light_intensity(segment *segp, int sidenum, int vert, fix intens
|
|||
// desired, but not entirely invalid. 2 reflects some light back to 0.
|
||||
static void apply_light_intensity(segment *segp, int sidenum, fix intensity, int depth)
|
||||
{
|
||||
int wid_result;
|
||||
|
||||
if (intensity == 0)
|
||||
return;
|
||||
|
||||
wid_result = WALL_IS_DOORWAY(segp, sidenum);
|
||||
if ((wid_result != WID_FLY_FLAG) && (wid_result != WID_NO_WALL)) {
|
||||
auto wid_result = WALL_IS_DOORWAY(segp, sidenum);
|
||||
if (!(wid_result & WID_RENDPAST_FLAG)) {
|
||||
int v;
|
||||
for (v=0; v<4; v++) // add light to this wall
|
||||
add_light_intensity(segp, sidenum, v, intensity);
|
||||
|
|
|
@ -2152,8 +2152,8 @@ static void init_boss_segments(boss_special_segment_array_t &segptr, int size_ch
|
|||
tail &= QUEUE_SIZE-1;
|
||||
|
||||
for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
|
||||
int w;
|
||||
if (((w = WALL_IS_DOORWAY(segp, sidenum)) & WID_FLY_FLAG) || one_wall_hack)
|
||||
auto w = WALL_IS_DOORWAY(segp, sidenum);
|
||||
if ((w & WID_FLY_FLAG) || one_wall_hack)
|
||||
{
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
// If we get here and w == WID_WALL, then we want to process through this wall, else not.
|
||||
|
|
|
@ -142,7 +142,7 @@ static void digi_get_sound_loc( const vms_matrix * listener, const vms_vector *
|
|||
int num_search_segs = f2i(max_distance/20);
|
||||
if ( num_search_segs < 1 ) num_search_segs = 1;
|
||||
|
||||
path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG+WID_FLY_FLAG );
|
||||
path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG|WID_FLY_FLAG );
|
||||
if ( path_distance > -1 ) {
|
||||
*volume = max_volume - fixdiv(path_distance,max_distance);
|
||||
if (*volume > 0 ) {
|
||||
|
|
|
@ -921,16 +921,13 @@ static int fvi_sub(vms_vector *intp,segnum_t *ints,const vms_vector *p0,segnum_t
|
|||
|
||||
|
||||
if (face_hit_type) { //through this wall/door
|
||||
int wid_flag;
|
||||
auto wid_flag = WALL_IS_DOORWAY(seg, side);
|
||||
|
||||
//if what we have hit is a door, check the adjoining seg
|
||||
|
||||
if ( (thisobjnum == Players[Player_num].objnum) && (cheats.ghostphysics) ) {
|
||||
wid_flag = WALL_IS_DOORWAY(seg, side);
|
||||
if (seg->children[side] >= 0 )
|
||||
wid_flag |= WID_FLY_FLAG;
|
||||
} else {
|
||||
wid_flag = WALL_IS_DOORWAY(seg, side);
|
||||
}
|
||||
|
||||
if ((wid_flag & WID_FLY_FLAG) ||
|
||||
|
|
|
@ -866,7 +866,7 @@ static void add_to_fcd_cache(int seg0, int seg1, int depth, fix dist)
|
|||
// Determine whether seg0 and seg1 are reachable in a way that allows sound to pass.
|
||||
// Search up to a maximum depth of max_depth.
|
||||
// Return the distance.
|
||||
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, int wid_flag)
|
||||
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, WALL_IS_DOORWAY_mask_t wid_flag)
|
||||
{
|
||||
segnum_t cur_seg;
|
||||
int sidenum;
|
||||
|
|
|
@ -160,7 +160,7 @@ static void apply_light(g3s_lrgb obj_light_emission, segnum_t obj_seg, vms_vecto
|
|||
|
||||
if (use_fcd_lighting && abs(obji_64) > F1_0*32)
|
||||
{
|
||||
dist = find_connected_distance(obj_pos, obj_seg, vertpos, vsegnum, n_render_vertices, WID_RENDPAST_FLAG+WID_FLY_FLAG);
|
||||
dist = find_connected_distance(obj_pos, obj_seg, vertpos, vsegnum, n_render_vertices, WID_RENDPAST_FLAG|WID_FLY_FLAG);
|
||||
if (dist >= 0)
|
||||
apply_light = 1;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ static inline int is_alphablend_eclip(int eclip_num)
|
|||
// they are used for our hideously hacked in headlight system.
|
||||
// vp is a pointer to vertex ids.
|
||||
// tmap1, tmap2 are texture map ids. tmap2 is the pasty one.
|
||||
static void render_face(segnum_t segnum, int sidenum, int nv, int *vp, int tmap1, int tmap2, uvl *uvlp, int wid_flags)
|
||||
static void render_face(segnum_t segnum, int sidenum, int nv, int *vp, int tmap1, int tmap2, uvl *uvlp, WALL_IS_DOORWAY_result_t wid_flags)
|
||||
{
|
||||
grs_bitmap *bm;
|
||||
#ifdef OGL
|
||||
|
@ -427,10 +427,7 @@ static void render_side(segment *segp, int sidenum)
|
|||
uvl temp_uvls[3];
|
||||
fix min_dot, max_dot;
|
||||
vms_vector normals[2];
|
||||
int wid_flags;
|
||||
|
||||
|
||||
wid_flags = WALL_IS_DOORWAY(segp,sidenum);
|
||||
auto wid_flags = WALL_IS_DOORWAY(segp,sidenum);
|
||||
|
||||
if (!(wid_flags & WID_RENDER_FLAG)) //if (WALL_IS_DOORWAY(segp, sidenum) == WID_NO_WALL)
|
||||
return;
|
||||
|
@ -1612,9 +1609,7 @@ static void build_segment_list(render_state_t &rstate, visited_twobit_array_t &v
|
|||
//tricky code to look at sides in correct order follows
|
||||
|
||||
for (c=n_children=0;c<MAX_SIDES_PER_SEGMENT;c++) { //build list of sides
|
||||
int wid;
|
||||
|
||||
wid = WALL_IS_DOORWAY(seg, c);
|
||||
auto wid = WALL_IS_DOORWAY(seg, c);
|
||||
if (wid & WID_RENDPAST_FLAG)
|
||||
{
|
||||
rotated=1;
|
||||
|
|
|
@ -100,7 +100,7 @@ static int check_transparency( segment * seg, int side )
|
|||
// WID_ILLUSORY_WALL 3 // 1/1/0 illusory wall
|
||||
// WID_TRANSILLUSORY_WALL 7 // 1/1/1 transparent illusory wall
|
||||
// WID_NO_WALL 5 // 1/0/1 no wall, can fly through
|
||||
int wall_is_doorway ( segment * seg, int side )
|
||||
WALL_IS_DOORWAY_result_t wall_is_doorway ( segment * seg, int side )
|
||||
{
|
||||
int flags, type;
|
||||
int state;
|
||||
|
@ -150,7 +150,7 @@ int wall_is_doorway ( segment * seg, int side )
|
|||
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
if (type == WALL_CLOAKED)
|
||||
return WID_RENDER_FLAG | WID_RENDPAST_FLAG | WID_CLOAKED_FLAG;
|
||||
return WID_CLOAKED_WALL;
|
||||
#endif
|
||||
|
||||
state = Walls[seg->sides[side].wall_num].state;
|
||||
|
|
Loading…
Reference in a new issue