diff --git a/common/main/gameseg.h b/common/main/gameseg.h index 0b67188d8..2bb75e6c3 100644 --- a/common/main/gameseg.h +++ b/common/main/gameseg.h @@ -40,8 +40,8 @@ namespace dcx { struct segmasks { short facemask; //which faces sphere pokes through (12 bits) - sbyte sidemask; //which sides sphere pokes through (6 bits) - sbyte centermask; //which sides center point is on back of (6 bits) + sidemask_t sidemask; //which sides sphere pokes through (6 bits) + sidemask_t centermask; //which sides center point is on back of (6 bits) }; struct segment_depth_array_t : public std::array {}; diff --git a/common/main/segment.h b/common/main/segment.h index 62c88dc52..42122888e 100644 --- a/common/main/segment.h +++ b/common/main/segment.h @@ -132,6 +132,31 @@ struct shared_side std::array normals; // 2 normals, if quadrilateral, both the same. }; +enum class sidemask_t : uint8_t +{ + left = 1u << static_cast(sidenum_t::WLEFT), + top = 1u << static_cast(sidenum_t::WTOP), + right = 1u << static_cast(sidenum_t::WRIGHT), + bottom = 1u << static_cast(sidenum_t::WBOTTOM), + back = 1u << static_cast(sidenum_t::WBACK), + front = 1u << static_cast(sidenum_t::WFRONT), +}; + +static constexpr uint8_t operator&(const sidemask_t a, const sidemask_t b) +{ + return static_cast(a) & static_cast(b); +} + +static constexpr sidemask_t &operator|=(sidemask_t &a, const sidemask_t b) +{ + return a = static_cast(static_cast(a) | static_cast(b)); +} + +static constexpr sidemask_t build_sidemask(const sidenum_t s) +{ + return static_cast(1u << static_cast(s)); +} + enum class texture1_value : uint16_t { None, @@ -249,7 +274,7 @@ struct unique_segment // If bit n (1 << n) is set, then side #n in segment has had light subtracted from original (editor-computed) value. uint8_t light_subtracted; /* if DXX_BUILD_DESCENT_II */ - uint8_t slide_textures; + sidemask_t slide_textures; /* endif */ fix static_light; enumerated_array sides; diff --git a/similar/editor/eobject.cpp b/similar/editor/eobject.cpp index f02f84433..f6070c1c5 100644 --- a/similar/editor/eobject.cpp +++ b/similar/editor/eobject.cpp @@ -470,7 +470,8 @@ static int move_object_within_mine(fvmobjptr &vmobjptr, segment_array &Segments, { range_for (const auto &&segp, Segments.vmptridx) { - if (get_seg_masks(vcvertptr, obj->pos, segp, 0).centermask == 0) { + if (get_seg_masks(vcvertptr, obj->pos, segp, 0).centermask == sidemask_t{}) + { int fate; fvi_info hit_info; fvi_query fq; diff --git a/similar/editor/kgame.cpp b/similar/editor/kgame.cpp index 03d9188ca..fcebde8e6 100644 --- a/similar/editor/kgame.cpp +++ b/similar/editor/kgame.cpp @@ -118,7 +118,7 @@ int SaveGameData() auto &vcvertptr = Vertices.vcptr; if (Perm_player_segnum!=segment_none) { - if (get_seg_masks(vcvertptr, Perm_player_position, vcsegptr(Perm_player_segnum), 0).centermask == 0) + if (get_seg_masks(vcvertptr, Perm_player_position, vcsegptr(Perm_player_segnum), 0).centermask == sidemask_t{}) { ConsoleObject->pos = Perm_player_position; ConsoleObject->orient = Perm_player_orient; diff --git a/similar/editor/mine.cpp b/similar/editor/mine.cpp index 0ea127399..057fe669b 100644 --- a/similar/editor/mine.cpp +++ b/similar/editor/mine.cpp @@ -519,11 +519,11 @@ static void dump_fix_as_ushort( fix value, int nbits, PHYSFS_File *SaveFile ) PHYSFS_writeULE16(SaveFile, short_value); } -static void write_children(const shared_segment &seg, const unsigned bit_mask, PHYSFS_File *const SaveFile) +static void write_children(const shared_segment &seg, const sidemask_t bit_mask, PHYSFS_File *const SaveFile) { for (const auto &&[bit, child] : enumerate(seg.children)) { - if (bit_mask & (1 << bit)) + if (bit_mask & build_sidemask(bit)) PHYSFS_writeSLE16(SaveFile, child); } } @@ -534,9 +534,9 @@ static void write_verts(const shared_segment &seg, PHYSFS_File *const SaveFile) PHYSFS_writeSLE16(SaveFile, static_cast(i)); } -static void write_special(const shared_segment &seg, const unsigned bit_mask, PHYSFS_File *const SaveFile) +static void write_special(const shared_segment &seg, const sidemask_t bit_mask, PHYSFS_File *const SaveFile) { - if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) + if (bit_mask & build_sidemask(MAX_SIDES_PER_SEGMENT)) { PHYSFSX_writeU8(SaveFile, underlying_value(seg.special)); PHYSFSX_writeU8(SaveFile, underlying_value(seg.matcen_num)); @@ -558,7 +558,6 @@ int save_mine_data_compiled(PHYSFS_File *SaveFile) { auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state(); ubyte version = COMPILED_MINE_VERSION; - ubyte bit_mask = 0; med_compress_mine(); warn_if_concave_segments(); @@ -597,19 +596,21 @@ int save_mine_data_compiled(PHYSFS_File *SaveFile) for (segnum_t segnum = 0; segnum < Num_segments; segnum++) { const cscusegment &&seg = vcsegptr(segnum); + { + sidemask_t bit_mask{}; for (const auto &&[sidenum, child] : enumerate(seg.s.children)) { if (child != segment_none) - bit_mask |= (1 << sidenum); + bit_mask |= build_sidemask(sidenum); } if (seg.s.special != segment_special::nothing || seg.s.matcen_num != materialization_center_number::None || seg.s.station_idx != station_number::None) - bit_mask |= (1 << MAX_SIDES_PER_SEGMENT); + bit_mask |= build_sidemask(MAX_SIDES_PER_SEGMENT); if (New_file_format_save) - PHYSFSX_writeU8(SaveFile, bit_mask); + PHYSFSX_writeU8(SaveFile, underlying_value(bit_mask)); else - bit_mask = 0x7F; + bit_mask = sidemask_t{0x7f}; if (Gamesave_current_version == 5) // d2 SHAREWARE level { @@ -627,26 +628,27 @@ int save_mine_data_compiled(PHYSFS_File *SaveFile) if (Gamesave_current_version <= 5) // descent 1 thru d2 SHAREWARE level dump_fix_as_ushort(seg.u.static_light, 4, SaveFile); - + } + // Write the walls as a 6 byte array - bit_mask = 0; + { + sidemask_t bit_mask{}; for (const auto &&[sidenum, side] : enumerate(seg.s.sides)) { if (side.wall_num != wall_none) - { - bit_mask |= (1 << sidenum); - } + bit_mask |= build_sidemask(sidenum); } if (New_file_format_save) - PHYSFSX_writeU8(SaveFile, bit_mask); + PHYSFSX_writeU8(SaveFile, underlying_value(bit_mask)); else - bit_mask = 0x3F; + bit_mask = sidemask_t{0x3f}; for (const auto &&[sidenum, side] : enumerate(seg.s.sides)) { - if (bit_mask & (1 << sidenum)) + if (bit_mask & build_sidemask(sidenum)) PHYSFSX_writeU8(SaveFile, underlying_value(side.wall_num)); } + } for (const auto sidenum : MAX_SIDES_PER_SEGMENT) { diff --git a/similar/main/fvi.cpp b/similar/main/fvi.cpp index 907bf10d5..bbf648144 100644 --- a/similar/main/fvi.cpp +++ b/similar/main/fvi.cpp @@ -659,7 +659,7 @@ int find_vector_intersection(const fvi_query &fq, fvi_info &hit_data) auto &vcvertptr = Vertices.vcptr; // Viewer is not in segment as claimed, so say there is no hit. - if(!(get_seg_masks(vcvertptr, *fq.p0, vcsegptr(fq.startseg), 0).centermask == 0)) + if (get_seg_masks(vcvertptr, *fq.p0, vcsegptr(fq.startseg), 0).centermask != sidemask_t{}) { hit_data.hit_type = HIT_BAD_P0; @@ -685,14 +685,14 @@ int find_vector_intersection(const fvi_query &fq, fvi_info &hit_data) const vms_vector *wall_norm = nullptr; //surface normal of hit wall hit_type = fvi_sub(hit_pnt, hit_seg2, *fq.p0, vcsegptridx(fq.startseg), *fq.p1, fq.rad, imobjptridx(fq.thisobjnum), fq.ignore_obj_list, fq.flags, hit_data.seglist, segment_exit, visited, fvi_hit_side, fvi_hit_side_seg, fvi_nest_count, fvi_hit_pt_seg, wall_norm, fvi_hit_object); segnum_t hit_seg; - if (hit_seg2 != segment_none && !get_seg_masks(vcvertptr, hit_pnt, vcsegptr(hit_seg2), 0).centermask) + if (hit_seg2 != segment_none && get_seg_masks(vcvertptr, hit_pnt, vcsegptr(hit_seg2), 0).centermask == sidemask_t{}) hit_seg = hit_seg2; else hit_seg = find_point_seg(LevelSharedSegmentState, LevelUniqueSegmentState, hit_pnt, imsegptridx(fq.startseg)); //MATT: TAKE OUT THIS HACK AND FIX THE BUGS! if (hit_type == HIT_WALL && hit_seg==segment_none) - if (fvi_hit_pt_seg != segment_none && get_seg_masks(vcvertptr, hit_pnt, vcsegptr(fvi_hit_pt_seg), 0).centermask == 0) + if (fvi_hit_pt_seg != segment_none && get_seg_masks(vcvertptr, hit_pnt, vcsegptr(fvi_hit_pt_seg), 0).centermask == sidemask_t{}) hit_seg = fvi_hit_pt_seg; if (hit_seg == segment_none) { @@ -810,7 +810,6 @@ static int fvi_sub(vms_vector &intp, segnum_t &ints, const vms_vector &p0, const auto &vcobjptridx = Objects.vcptridx; int startmask,endmask; //mask of faces //@@int sidemask; //mask of sides - can be on back of face but not side - int centermask; //where the center point is vms_vector closest_hit_point{}; //where we hit auto closest_d = vm_distance_squared::maximum_value(); //distance to hit point int hit_type=HIT_NONE; //what sort of hit @@ -897,9 +896,10 @@ static int fvi_sub(vms_vector &intp, segnum_t &ints, const vms_vector &p0, const const auto &&masks = get_seg_masks(vcvertptr, p1, startseg, rad); //on back of which faces? endmask = masks.facemask; //@@sidemask = masks.sidemask; - centermask = masks.centermask; + const auto centermask = masks.centermask; //where the center point is - if (centermask==0) hit_none_seg = startseg; + if (centermask == sidemask_t{}) + hit_none_seg = startseg; if (endmask != 0) { //on the back of at least one face @@ -1026,7 +1026,7 @@ static int fvi_sub(vms_vector &intp, segnum_t &ints, const vms_vector &p0, const closest_hit_point = hit_point; hit_type = HIT_WALL; wall_norm = &startseg->shared_segment::sides[side].normals[face]; - if (get_seg_masks(vcvertptr, hit_point, startseg, rad).centermask == 0) + if (get_seg_masks(vcvertptr, hit_point, startseg, rad).centermask == sidemask_t{}) hit_seg = startseg; //hit in this segment else fvi_hit_pt_seg = startseg; diff --git a/similar/main/game.cpp b/similar/main/game.cpp index a80d93a9c..dd0180922 100644 --- a/similar/main/game.cpp +++ b/similar/main/game.cpp @@ -2113,7 +2113,7 @@ void compute_slide_segs() auto &TmapInfo = LevelUniqueTmapInfoState.TmapInfo; for (const csmusegment suseg : vmsegptr) { - uint8_t slide_textures = 0; + sidemask_t slide_textures{}; for (const auto sidenum : MAX_SIDES_PER_SEGMENT) { const auto &uside = suseg.u.sides[sidenum]; @@ -2127,7 +2127,7 @@ void compute_slide_segs() * walls. */ continue; - slide_textures |= 1 << sidenum; + slide_textures |= build_sidemask(sidenum); } suseg.u.slide_textures = slide_textures; } @@ -2155,11 +2155,11 @@ static void slide_textures(void) auto &TmapInfo = LevelUniqueTmapInfoState.TmapInfo; for (unique_segment &useg : vmsegptr) { - if (const auto slide_seg = useg.slide_textures) + if (const auto slide_seg = useg.slide_textures; slide_seg != sidemask_t{}) { for (const auto sidenum : MAX_SIDES_PER_SEGMENT) { - if (slide_seg & (1 << sidenum)) + if (slide_seg & build_sidemask(sidenum)) { auto &side = useg.sides[sidenum]; const auto &ti = TmapInfo[get_texture_index(side.tmap_num)]; diff --git a/similar/main/gamemine.cpp b/similar/main/gamemine.cpp index 336c91d79..d5080185e 100644 --- a/similar/main/gamemine.cpp +++ b/similar/main/gamemine.cpp @@ -402,11 +402,12 @@ struct me mine_editor; namespace { -static void read_children(shared_segment &segp, const unsigned bit_mask, PHYSFS_File *const LoadFile) +static void read_children(shared_segment &segp, const sidemask_t bit_mask, PHYSFS_File *const LoadFile) { for (const auto bit : MAX_SIDES_PER_SEGMENT) { - if (bit_mask & (1 << bit)) { + if (bit_mask & build_sidemask(bit)) + { segp.children[bit] = PHYSFSX_readShort(LoadFile); } else segp.children[bit] = segment_none; @@ -425,9 +426,10 @@ static void read_verts(shared_segment &segp, PHYSFS_File *const LoadFile) } } -static void read_special(shared_segment &segp, const unsigned bit_mask, PHYSFS_File *const LoadFile) +static void read_special(shared_segment &segp, const sidemask_t bit_mask, PHYSFS_File *const LoadFile) { - if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) { + if (bit_mask & build_sidemask(MAX_SIDES_PER_SEGMENT)) + { // Read ubyte Segments[segnum].special segp.special = build_segment_special_from_untrusted(PHYSFSX_readByte(LoadFile)); // Read byte Segments[segnum].matcen_num @@ -451,7 +453,6 @@ int load_mine_data_compiled(PHYSFS_File *LoadFile, const char *const Gamesave_cu auto &Vertices = LevelSharedVertexState.get_vertices(); ubyte compiled_version; short temp_short; - ubyte bit_mask; #if defined(DXX_BUILD_DESCENT_II) LevelSharedSeismicState.Level_shake_frequency = 0; @@ -508,20 +509,19 @@ int load_mine_data_compiled(PHYSFS_File *LoadFile, const char *const Gamesave_cu segp.s.group = 0; #endif - if (New_file_format_load) - bit_mask = PHYSFSX_readByte(LoadFile); - else - bit_mask = 0x7f; // read all six children and special stuff... + const sidemask_t children_mask = New_file_format_load + ? static_cast(PHYSFSX_readByte(LoadFile)) + : sidemask_t{0x7f}; // read all six children and special stuff... if (Gamesave_current_version == 5) { // d2 SHAREWARE level - read_special(segp,bit_mask,LoadFile); + read_special(segp, children_mask, LoadFile); read_verts(segp,LoadFile); - read_children(segp,bit_mask,LoadFile); + read_children(segp, children_mask, LoadFile); } else { - read_children(segp,bit_mask,LoadFile); + read_children(segp, children_mask, LoadFile); read_verts(segp,LoadFile); if (Gamesave_current_version <= 1) { // descent 1 level - read_special(segp,bit_mask,LoadFile); + read_special(segp, children_mask, LoadFile); } } @@ -534,14 +534,14 @@ int load_mine_data_compiled(PHYSFS_File *LoadFile, const char *const Gamesave_cu } // Read the walls as a 6 byte array - if (New_file_format_load) - bit_mask = PHYSFSX_readByte(LoadFile); - else - bit_mask = 0x3f; // read all six sides + const sidemask_t wall_mask = New_file_format_load + ? static_cast(PHYSFSX_readByte(LoadFile)) + : sidemask_t{0x3f}; // read all six sides for (const auto sidenum : MAX_SIDES_PER_SEGMENT) { auto &sside = segp.s.sides[sidenum]; - if (bit_mask & (1 << sidenum)) { + if (wall_mask & build_sidemask(sidenum)) + { const uint8_t byte_wallnum = PHYSFSX_readByte(LoadFile); if ( byte_wallnum == 255 ) sside.wall_num = wall_none; diff --git a/similar/main/gameseg.cpp b/similar/main/gameseg.cpp index 134e9e72a..8ebfeac83 100644 --- a/similar/main/gameseg.cpp +++ b/similar/main/gameseg.cpp @@ -297,7 +297,7 @@ segmasks get_seg_masks(fvcvertptr &vcvertptr, const vms_vector &checkp, const sh int facebit = 1; for (const auto sn : MAX_SIDES_PER_SEGMENT) { - const auto sidebit = 1 << sn; + const auto sidebit = build_sidemask(sn); auto &s = seg.sides[sn]; // Get number of faces on this side, and at vertex_list, store vertices. @@ -383,20 +383,17 @@ namespace { //this was converted from get_seg_masks()...it fills in an array of 6 //elements for the distace behind each side, or zero if not behind //only gets centermask, and assumes zero rad -static uint8_t get_side_dists(fvcvertptr &vcvertptr, const vms_vector &checkp, const shared_segment &segnum, std::array &side_dists) +static sidemask_t get_side_dists(fvcvertptr &vcvertptr, const vms_vector &checkp, const shared_segment &segnum, std::array &side_dists) { - ubyte mask; + sidemask_t mask{}; auto &sides = segnum.sides; //check point against each side of segment. return bitmask - - mask = 0; - side_dists = {}; int facebit = 1; for (const auto sn : MAX_SIDES_PER_SEGMENT) { - const auto sidebit = 1 << sn; + const auto sidebit = build_sidemask(sn); auto &s = sides[sn]; // Get number of faces on this side, and at vertex_list, store vertices. @@ -616,7 +613,6 @@ namespace { // returns segment number, or -1 if can't find segment static icsegptridx_t trace_segs(const d_level_shared_segment_state &LevelSharedSegmentState, const vms_vector &p0, const vcsegptridx_t oldsegnum, const unsigned recursion_count, visited_segment_bitarray_t &visited) { - int centermask; std::array side_dists; fix biggest_val; if (recursion_count >= LevelSharedSegmentState.Num_segments) { @@ -630,8 +626,8 @@ static icsegptridx_t trace_segs(const d_level_shared_segment_state &LevelSharedS auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state(); auto &Vertices = LevelSharedVertexState.get_vertices(); - centermask = get_side_dists(Vertices.vcptr, p0, oldsegnum, side_dists); //check old segment - if (centermask == 0) // we are in the old segment + const auto centermask = get_side_dists(Vertices.vcptr, p0, oldsegnum, side_dists); //check old segment + if (centermask == sidemask_t{}) // we are in the old segment return oldsegnum; //..say so for (;;) { @@ -640,7 +636,7 @@ static icsegptridx_t trace_segs(const d_level_shared_segment_state &LevelSharedS biggest_val = 0; for (const auto sidenum : MAX_SIDES_PER_SEGMENT) { - const auto bit = 1 << sidenum; + const auto bit = build_sidemask(sidenum); if ((centermask & bit) && IS_CHILD(children[sidenum]) && side_dists[sidenum] < biggest_val) { biggest_val = side_dists[sidenum]; @@ -693,7 +689,7 @@ icsegptridx_t find_point_seg(const d_level_shared_segment_state &LevelSharedSegm auto &Vertices = LevelSharedVertexState.get_vertices(); range_for (const auto &&segp, Segments.vmptridx) { - if (get_seg_masks(Vertices.vcptr, p, segp, 0).centermask == 0) + if (get_seg_masks(Vertices.vcptr, p, segp, 0).centermask == sidemask_t{}) return segp; } } diff --git a/similar/main/gameseq.cpp b/similar/main/gameseq.cpp index 7601df63b..36a814e73 100644 --- a/similar/main/gameseq.cpp +++ b/similar/main/gameseq.cpp @@ -254,7 +254,7 @@ static bool operator!=(const vms_vector &a, const vms_vector &b) constexpr constant_xrange displacement_sides{}; static_assert(WBACK + 1 == WFRONT, "side ordering error"); -static unsigned generate_extra_starts_by_copying(object_array &Objects, valptridx::array_managed_type &Players, segment_array &Segments, const xrange> preplaced_start_range, const std::array &player_init_segment_capacity_flag, const unsigned total_required_num_starts, unsigned synthetic_player_idx) +static unsigned generate_extra_starts_by_copying(object_array &Objects, valptridx::array_managed_type &Players, segment_array &Segments, const xrange> preplaced_start_range, const std::array &player_init_segment_capacity_flag, const unsigned total_required_num_starts, unsigned synthetic_player_idx) { for (const auto side : displacement_sides) { @@ -263,7 +263,7 @@ static unsigned generate_extra_starts_by_copying(object_array &Objects, valptrid auto &old_player_ref = *Players.vcptr(old_player_idx); const auto &&old_player_ptridx = Objects.vcptridx(old_player_ref.objnum); auto &old_player_obj = *old_player_ptridx; - if (player_init_segment_capacity_flag[old_player_idx] & (1 << side)) + if (player_init_segment_capacity_flag[old_player_idx] & build_sidemask(side)) { auto &&segp = Segments.vmptridx(old_player_obj.segnum); /* Copy the start exactly. The next loop in the caller will @@ -301,13 +301,13 @@ static unsigned generate_extra_starts_by_displacement_within_segment(const unsig auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcobjptr = Objects.vcptr; auto &vmobjptr = Objects.vmptr; - std::array player_init_segment_capacity_flag{}; + std::array player_init_segment_capacity_flag{}; DXX_MAKE_VAR_UNDEFINED(player_init_segment_capacity_flag); static_assert(WRIGHT + 1 == WBOTTOM, "side ordering error"); static_assert(WBOTTOM + 1 == WBACK, "side ordering error"); - constexpr uint8_t capacity_x = 1 << WRIGHT; - constexpr uint8_t capacity_y = 1 << WBOTTOM; - constexpr uint8_t capacity_z = 1 << WBACK; + constexpr auto capacity_x = build_sidemask(WRIGHT); + constexpr auto capacity_y = build_sidemask(WBOTTOM); + constexpr auto capacity_z = build_sidemask(WBACK); /* When players are displaced, they are moved by their size * multiplied by this constant. Larger values provide more * separation between the player starts, but increase the chance @@ -329,7 +329,7 @@ static unsigned generate_extra_starts_by_displacement_within_segment(const unsig auto &old_player_obj = *vcobjptr(plr.objnum); const vm_distance_squared size2(fixmul64(old_player_obj.size * old_player_obj.size, size_scalar)); auto &v0 = *vcvertptr(seg.verts[segment_relative_vertnum::_0]); - uint8_t capacity_flag = 0; + sidemask_t capacity_flag{}; if (vm_vec_dist2(v0, vcvertptr(seg.verts[segment_relative_vertnum::_1])) > size2) capacity_flag |= capacity_x; if (vm_vec_dist2(v0, vcvertptr(seg.verts[segment_relative_vertnum::_3])) > size2) @@ -337,8 +337,8 @@ static unsigned generate_extra_starts_by_displacement_within_segment(const unsig if (vm_vec_dist2(v0, vcvertptr(seg.verts[segment_relative_vertnum::_4])) > size2) capacity_flag |= capacity_z; player_init_segment_capacity_flag[i] = capacity_flag; - con_printf(CON_NORMAL, "Original player %u has size %u, starts in segment #%hu, and has segment capacity flags %x.", i, old_player_obj.size, static_cast(segnum), capacity_flag); - if (capacity_flag) + con_printf(CON_NORMAL, "Original player %u has size %u, starts in segment #%hu, and has segment capacity flags %x.", i, old_player_obj.size, static_cast(segnum), underlying_value(capacity_flag)); + if (capacity_flag != sidemask_t{}) ++segments_with_spare_capacity; } if (!segments_with_spare_capacity) @@ -369,7 +369,7 @@ static unsigned generate_extra_starts_by_displacement_within_segment(const unsig unsigned dimensions = 0; for (const auto &&[i, side] : enumerate(displacement_sides)) { - if (!(player_init_segment_capacity_flag[old_player_idx] & (1 << side))) + if (!(player_init_segment_capacity_flag[old_player_idx] & build_sidemask(side))) { con_printf(CON_NORMAL, "Cannot displace player %u at {%i, %i, %i}: not enough room in dimension %u.", plridx, plrobj.pos.x, plrobj.pos.y, plrobj.pos.z, side); continue; @@ -385,9 +385,9 @@ static unsigned generate_extra_starts_by_displacement_within_segment(const unsig vm_vec_normalize(disp); vm_vec_scale(disp, fixmul(old_player_obj.size, size_scalar >> 1)); const auto target_position = vm_vec_add(Player_init[plridx].pos, disp); - if (const auto sidemask = get_seg_masks(vcvertptr, target_position, vcsegptr(plrobj.segnum), 1).sidemask) + if (const auto sidemask = get_seg_masks(vcvertptr, target_position, vcsegptr(plrobj.segnum), 1).sidemask; sidemask != sidemask_t{}) { - con_printf(CON_NORMAL, "Cannot displace player %u at {%i, %i, %i} to {%i, %i, %i}: would be outside segment for sides %x.", plridx, plrobj.pos.x, plrobj.pos.y, plrobj.pos.z, target_position.x, target_position.y, target_position.z, sidemask); + con_printf(CON_NORMAL, "Cannot displace player %u at {%i, %i, %i} to {%i, %i, %i}: would be outside segment for sides %x.", plridx, plrobj.pos.x, plrobj.pos.y, plrobj.pos.z, target_position.x, target_position.y, target_position.z, underlying_value(sidemask)); return; } con_printf(CON_NORMAL, "Displace player %u at {%i, %i, %i} by {%i, %i, %i} to {%i, %i, %i}.", plridx, plrobj.pos.x, plrobj.pos.y, plrobj.pos.z, disp.x, disp.y, disp.z, target_position.x, target_position.y, target_position.z); diff --git a/similar/main/object.cpp b/similar/main/object.cpp index f0023a447..37586115f 100644 --- a/similar/main/object.cpp +++ b/similar/main/object.cpp @@ -1122,7 +1122,7 @@ imobjptridx_t obj_create(const object_type_t type, const unsigned id, vmsegptrid return object_none; auto &vcvertptr = Vertices.vcptr; - if (get_seg_masks(vcvertptr, pos, segnum, 0).centermask != 0) + if (get_seg_masks(vcvertptr, pos, segnum, 0).centermask != sidemask_t{}) { const auto &&p = find_point_seg(LevelSharedSegmentState, LevelUniqueSegmentState, pos, segnum); if (p == segment_none) { @@ -1932,11 +1932,11 @@ static window_event_result object_move_one(const vmobjptridx_t obj, control_info auto &playing = obj->ctype.player_info.lavafall_hiss_playing; const auto &&segp = vcsegptr(obj->segnum); auto &vcvertptr = Vertices.vcptr; - if (const auto sidemask = get_seg_masks(vcvertptr, obj->pos, segp, obj->size).sidemask) + if (const auto sidemask = get_seg_masks(vcvertptr, obj->pos, segp, obj->size).sidemask; sidemask != sidemask_t{}) { for (const auto sidenum : MAX_SIDES_PER_SEGMENT) { - if (!(sidemask & (1 << sidenum))) + if (!(sidemask & build_sidemask(sidenum))) continue; const auto wall_num = segp->shared_segment::sides[sidenum].wall_num; if (wall_num != wall_none && vcwallptr(wall_num)->type == WALL_ILLUSION) diff --git a/similar/main/physics.cpp b/similar/main/physics.cpp index 052725099..cc0fda739 100644 --- a/similar/main/physics.cpp +++ b/similar/main/physics.cpp @@ -493,7 +493,7 @@ window_event_result do_physics_sim(const vmobjptridx_t obj, const vms_vector &ob obj_relink(vmobjptr, Segments.vmptr, obj, obj_segp); //if start point not in segment, move object to center of segment - if (get_seg_masks(vcvertptr, obj->pos, Segments.vcptr(obj->segnum), 0).centermask != 0) + if (get_seg_masks(vcvertptr, obj->pos, Segments.vcptr(obj->segnum), 0).centermask != sidemask_t{}) { auto n = find_object_seg(LevelSharedSegmentState, LevelUniqueSegmentState, obj); if (n == segment_none) @@ -773,7 +773,7 @@ window_event_result do_physics_sim(const vmobjptridx_t obj, const vms_vector &ob //--WE ALWYS WANT THIS IN, MATT AND MIKE DECISION ON 12/10/94, TWO MONTHS AFTER FINAL #ifndef NDEBUG //if end point not in segment, move object to last pos, or segment center - if (get_seg_masks(vcvertptr, obj->pos, vcsegptr(obj->segnum), 0).centermask != 0) + if (get_seg_masks(vcvertptr, obj->pos, vcsegptr(obj->segnum), 0).centermask != sidemask_t{}) { if (find_object_seg(LevelSharedSegmentState, LevelUniqueSegmentState, obj) == segment_none) { diff --git a/similar/main/render.cpp b/similar/main/render.cpp index 91231f546..006fc1772 100644 --- a/similar/main/render.cpp +++ b/similar/main/render.cpp @@ -1187,12 +1187,11 @@ static void build_object_lists(object_array &Objects, fvcsegptr &vcsegptr, const #if defined(DXX_BUILD_DESCENT_I) did_migrate = 0; #endif - const uint_fast32_t sidemask = get_seg_masks(vcvertptr, obj->pos, vcsegptr(new_segnum), obj->size).sidemask; - - if (sidemask) { + if (const auto sidemask = get_seg_masks(vcvertptr, obj->pos, vcsegptr(new_segnum), obj->size).sidemask; sidemask != sidemask_t{}) + { for (const auto sn : MAX_SIDES_PER_SEGMENT) { - const auto sf = 1 << sn; + const auto sf = build_sidemask(sn); if (sidemask & sf) { #if defined(DXX_BUILD_DESCENT_I) @@ -1220,7 +1219,6 @@ static void build_object_lists(object_array &Objects, fvcsegptr &vcsegptr, const } } } - } while (did_migrate); add_obj_to_seglist(rstate, obj, new_segnum); } diff --git a/similar/main/wall.cpp b/similar/main/wall.cpp index d41e47132..e44306f49 100644 --- a/similar/main/wall.cpp +++ b/similar/main/wall.cpp @@ -719,12 +719,12 @@ namespace dcx { namespace { -static unsigned check_poke(fvcvertptr &vcvertptr, const object_base &obj, const shared_segment &seg, const unsigned side) +static unsigned check_poke(fvcvertptr &vcvertptr, const object_base &obj, const shared_segment &seg, const sidenum_t side) { //note: don't let objects with zero size block door if (!obj.size) return 0; - return get_seg_masks(vcvertptr, obj.pos, seg, obj.size).sidemask & (1 << side); //pokes through side! + return get_seg_masks(vcvertptr, obj.pos, seg, obj.size).sidemask & build_sidemask(side); //pokes through side! } } @@ -735,7 +735,7 @@ namespace dsx { namespace { -static unsigned is_door_side_obstructed(fvcobjptridx &vcobjptridx, fvcsegptr &vcsegptr, const cscusegment seg, const unsigned side) +static unsigned is_door_side_obstructed(fvcobjptridx &vcobjptridx, fvcsegptr &vcsegptr, const cscusegment seg, const sidenum_t side) { auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state(); auto &Vertices = LevelSharedVertexState.get_vertices();