Use dedicated type for mask of segment side numbers
This commit is contained in:
parent
8c037b7c26
commit
2fe9a16613
|
@ -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> {};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue