From 02e2e77ee6f4efdba92de37936809f2032cae103 Mon Sep 17 00:00:00 2001 From: Kp Date: Sat, 6 Sep 2014 22:26:11 +0000 Subject: [PATCH] Tighten processing of WALL_IS_DOORWAY flags --- common/main/gameseg.h | 3 +- common/main/wall.h | 99 +++++++++++++++++++++++++++++++++------ similar/editor/elight.cpp | 6 +-- similar/main/ai.cpp | 4 +- similar/main/digiobj.cpp | 2 +- similar/main/fvi.cpp | 5 +- similar/main/gameseg.cpp | 2 +- similar/main/lighting.cpp | 2 +- similar/main/render.cpp | 11 ++--- similar/main/wall.cpp | 4 +- 10 files changed, 99 insertions(+), 39 deletions(-) diff --git a/common/main/gameseg.h b/common/main/gameseg.h index 47ac22d75..8d94759bc 100644 --- a/common/main/gameseg.h +++ b/common/main/gameseg.h @@ -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); diff --git a/common/main/wall.h b/common/main/wall.h index 2c268e7ba..be27c43f3 100644 --- a/common/main/wall.h +++ b/common/main/wall.h @@ -100,22 +100,93 @@ struct vobjptridx_t; #define MAX_CLIP_FRAMES 50 #endif +template +struct WALL_IS_DOORWAY_FLAG +{ + constexpr operator unsigned() const { return value; } + template + constexpr WALL_IS_DOORWAY_FLAG operator|(WALL_IS_DOORWAY_FLAG) + { + return {}; + } +}; + +template +struct WALL_IS_DOORWAY_sresult_t +{ +}; + +template +static inline constexpr WALL_IS_DOORWAY_sresult_t WALL_IS_DOORWAY_sresult(WALL_IS_DOORWAY_FLAG) +{ + return {}; +} + +struct WALL_IS_DOORWAY_mask_t +{ + unsigned value; + template + constexpr WALL_IS_DOORWAY_mask_t(WALL_IS_DOORWAY_FLAG) : + value(F) + { + } +}; + +struct WALL_IS_DOORWAY_result_t +{ + unsigned value; + template + constexpr WALL_IS_DOORWAY_result_t(WALL_IS_DOORWAY_sresult_t) : + value(F) + { + } + template + unsigned operator&(WALL_IS_DOORWAY_FLAG) const + { + return value & F; + } + template + WALL_IS_DOORWAY_result_t operator|=(WALL_IS_DOORWAY_FLAG) + { + value |= F; + return *this; + } + template + bool operator==(WALL_IS_DOORWAY_sresult_t) 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 + 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 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 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; diff --git a/similar/editor/elight.cpp b/similar/editor/elight.cpp index dd0432df6..9a98f1093 100644 --- a/similar/editor/elight.cpp +++ b/similar/editor/elight.cpp @@ -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); diff --git a/similar/main/ai.cpp b/similar/main/ai.cpp index 77c5add28..840e1ae8e 100644 --- a/similar/main/ai.cpp +++ b/similar/main/ai.cpp @@ -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 -1 ) { *volume = max_volume - fixdiv(path_distance,max_distance); if (*volume > 0 ) { diff --git a/similar/main/fvi.cpp b/similar/main/fvi.cpp index a9b592a8a..a0e116eae 100644 --- a/similar/main/fvi.cpp +++ b/similar/main/fvi.cpp @@ -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) || diff --git a/similar/main/gameseg.cpp b/similar/main/gameseg.cpp index 3ea6fac02..9945d4873 100644 --- a/similar/main/gameseg.cpp +++ b/similar/main/gameseg.cpp @@ -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; diff --git a/similar/main/lighting.cpp b/similar/main/lighting.cpp index 0836a65b9..3282f37ba 100644 --- a/similar/main/lighting.cpp +++ b/similar/main/lighting.cpp @@ -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; } diff --git a/similar/main/render.cpp b/similar/main/render.cpp index e386e9341..df35bb6db 100644 --- a/similar/main/render.cpp +++ b/similar/main/render.cpp @@ -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;csides[side].wall_num].state;