Use dedicated type for mask of segment side numbers

This commit is contained in:
Kp 2022-02-19 14:52:17 +00:00
parent 8c037b7c26
commit 2fe9a16613
14 changed files with 110 additions and 88 deletions

View file

@ -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<ubyte, MAX_SEGMENTS> {};

View file

@ -132,6 +132,31 @@ struct shared_side
std::array<vms_vector, 2> normals; // 2 normals, if quadrilateral, both the same.
};
enum class sidemask_t : uint8_t
{
left = 1u << static_cast<uint8_t>(sidenum_t::WLEFT),
top = 1u << static_cast<uint8_t>(sidenum_t::WTOP),
right = 1u << static_cast<uint8_t>(sidenum_t::WRIGHT),
bottom = 1u << static_cast<uint8_t>(sidenum_t::WBOTTOM),
back = 1u << static_cast<uint8_t>(sidenum_t::WBACK),
front = 1u << static_cast<uint8_t>(sidenum_t::WFRONT),
};
static constexpr uint8_t operator&(const sidemask_t a, const sidemask_t b)
{
return static_cast<uint8_t>(a) & static_cast<uint8_t>(b);
}
static constexpr sidemask_t &operator|=(sidemask_t &a, const sidemask_t b)
{
return a = static_cast<sidemask_t>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
}
static constexpr sidemask_t build_sidemask(const sidenum_t s)
{
return static_cast<sidemask_t>(1u << static_cast<uint8_t>(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<unique_side, MAX_SIDES_PER_SEGMENT, sidenum_t> sides;

View file

@ -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;

View file

@ -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;

View file

@ -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<uint16_t>(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)
{

View file

@ -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;

View file

@ -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)];

View file

@ -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<sidemask_t>(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<sidemask_t>(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;

View file

@ -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<fix, 6> &side_dists)
static sidemask_t get_side_dists(fvcvertptr &vcvertptr, const vms_vector &checkp, const shared_segment &segnum, std::array<fix, 6> &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<fix, 6> 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;
}
}

View file

@ -254,7 +254,7 @@ static bool operator!=(const vms_vector &a, const vms_vector &b)
constexpr constant_xrange<sidenum_t, sidenum_t::WRIGHT, sidenum_t::WFRONT> displacement_sides{};
static_assert(WBACK + 1 == WFRONT, "side ordering error");
static unsigned generate_extra_starts_by_copying(object_array &Objects, valptridx<player>::array_managed_type &Players, segment_array &Segments, const xrange<unsigned, std::integral_constant<unsigned, 0>> preplaced_start_range, const std::array<uint8_t, MAX_PLAYERS> &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<player>::array_managed_type &Players, segment_array &Segments, const xrange<unsigned, std::integral_constant<unsigned, 0>> preplaced_start_range, const std::array<sidemask_t, MAX_PLAYERS> &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<uint8_t, MAX_PLAYERS> player_init_segment_capacity_flag{};
std::array<sidemask_t, MAX_PLAYERS> 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_t>(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_t>(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);

View file

@ -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)

View file

@ -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)
{

View file

@ -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);
}

View file

@ -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();