dxx-rebirth/common/main/wall.h
Kp 2a6c513ffd Fix LTO ODR build failure in wall.h
The conditional definition of a D2X flag causes a technical ODR
violation.  It is legal, though not useful, to define this flag in D1X
and in common code.  Remove the preprocessor guard so that D2X and
common code use the same definition for the enum.
2022-04-17 22:27:19 +00:00

300 lines
8.3 KiB
C++

/*
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING.txt.
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below.
* See COPYING.txt for license details.
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
*/
/*
*
* Header for wall.c
*
*/
#pragma once
#include "dsx-ns.h"
#include "fwd-segment.h"
#include "fwd-wall.h"
#include "fwd-object.h"
#include "pack.h"
#include "switch.h"
#include "d_underlying_value.h"
namespace dcx {
enum class wall_key : uint8_t
{
none = 1,
blue = 2,
red = 4,
gold = 8,
};
constexpr uint8_t operator&(const wall_key a, const wall_key b)
{
return underlying_value(a) & underlying_value(b);
}
#if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
struct WALL_IS_DOORWAY_mask_t
{
uint8_t value;
constexpr WALL_IS_DOORWAY_mask_t(WALL_IS_DOORWAY_FLAG F) :
value(static_cast<uint8_t>(F))
{
}
};
struct WALL_IS_DOORWAY_result_t
{
uint8_t value;
constexpr WALL_IS_DOORWAY_result_t(const WALL_IS_DOORWAY_sresult_t f) :
value(static_cast<unsigned>(f))
{
}
unsigned operator&(WALL_IS_DOORWAY_FLAG f) const
{
return value & static_cast<uint8_t>(f);
}
WALL_IS_DOORWAY_result_t &operator|=(WALL_IS_DOORWAY_FLAG f)
{
value |= static_cast<uint8_t>(f);
return *this;
}
bool operator==(WALL_IS_DOORWAY_sresult_t F) const
{
return value == static_cast<unsigned>(F);
}
bool operator&(WALL_IS_DOORWAY_mask_t m) const
{
return value & m.value;
}
bool operator==(WALL_IS_DOORWAY_result_t) const = delete;
template <typename T>
bool operator!=(const T &t) const
{
return !(*this == t);
}
};
struct stuckobj : public prohibit_void_ptr<stuckobj>
{
objnum_t objnum = object_none;
wallnum_t wallnum = wall_none;
};
#endif
//Start old wall structures
struct v16_wall : public prohibit_void_ptr<v16_wall>
{
sbyte type; // What kind of special wall.
sbyte flags; // Flags for the wall.
uint8_t trigger; // Which trigger is associated with the wall.
fix hps; // "Hit points" of the wall.
sbyte clip_num; // Which animation associated with the wall.
sbyte keys;
};
struct v19_wall : public prohibit_void_ptr<v19_wall>
{
segnum_t segnum;
sbyte type; // What kind of special wall.
sbyte flags; // Flags for the wall.
int sidenum; // Seg & side for this wall
fix hps; // "Hit points" of the wall.
uint8_t trigger; // Which trigger is associated with the wall.
sbyte clip_num; // Which animation associated with the wall.
sbyte keys;
wallnum_t linked_wall; // number of linked wall
};
#ifdef dsx
class d_level_unique_stuck_object_state
{
protected:
unsigned Num_stuck_objects = 0;
std::array<stuckobj, 32> Stuck_objects;
public:
void init_stuck_objects();
};
#endif
enum class wall_flag : uint8_t
{
blasted = 1, // Blasted out wall.
door_opened = 1u << 1, // Open door.
door_locked = 1u << 3, // Door is locked.
door_auto = 1u << 4, // Door automatically closes after time.
illusion_off = 1u << 5, // Illusionary wall is shut off.
exploding = 1u << 6,
/* if DXX_BUILD_DESCENT_II */
buddy_proof = 1u << 7, // Buddy assumes he cannot get through this wall.
/* endif */
};
enum class wall_flags : uint8_t;
enum class wall_state : uint8_t
{
closed, // Door is closed
opening, // Door is opening.
waiting, // Waiting to close
closing, // Door is closing
/* if DXX_BUILD_DESCENT_II */
open, // Door is open, and staying open
cloaking, // Wall is going from closed -> open
decloaking, // Wall is going from open -> closed
/* endif */
};
static constexpr auto &operator|=(wall_flags &wall, const wall_flag f)
{
return wall = static_cast<wall_flags>(underlying_value(wall) | underlying_value(f));
}
static constexpr auto &operator&=(wall_flags &wall, const wall_flag f)
{
return wall = static_cast<wall_flags>(underlying_value(wall) & underlying_value(f));
}
static constexpr auto operator~(const wall_flag f)
{
return static_cast<wall_flag>(~underlying_value(f));
}
static constexpr auto operator&(const wall_flags wall, const wall_flag f)
{
return underlying_value(wall) & underlying_value(f);
}
static constexpr auto operator|(const wall_flag f1, const wall_flag f2)
{
return static_cast<wall_flag>(underlying_value(f1) | underlying_value(f2));
}
}
//End old wall structures
#ifdef dsx
namespace dsx {
/* No shared state is possible for this structure, but include the
* `unique` qualifier to document its status.
*/
class d_level_unique_stuck_object_state : public ::dcx::d_level_unique_stuck_object_state
{
public:
void add_stuck_object(fvcwallptr &, vmobjptridx_t objp, const shared_segment &segp, sidenum_t sidenum);
void remove_stuck_object(vcobjidx_t);
void kill_stuck_objects(fvmobjptr &, vcwallidx_t wallnum);
};
extern d_level_unique_stuck_object_state LevelUniqueStuckObjectState;
struct wall : public prohibit_void_ptr<wall>
{
segnum_t segnum;
sidenum_t sidenum; // Seg & side for this wall
uint8_t type; // What kind of special wall.
fix hps; // "Hit points" of the wall.
uint16_t explode_time_elapsed;
wallnum_t linked_wall; // number of linked wall
wall_flags flags; // Flags for the wall.
wall_state state; // Opening, closing, etc.
trgnum_t trigger; // Which trigger is associated with the wall.
sbyte clip_num; // Which animation associated with the wall.
wall_key keys; // which keys are required
#if defined(DXX_BUILD_DESCENT_II)
trgnum_t controlling_trigger;// which trigger causes something to happen here. Not like "trigger" above, which is the trigger on this wall.
// Note: This gets stuffed at load time in gamemine.c. Don't try to use it in the editor. You will be sorry!
sbyte cloak_value; // if this wall is cloaked, the fade value
#endif
};
}
namespace dcx {
struct active_door : public prohibit_void_ptr<active_door>
{
unsigned n_parts; // for linked walls
std::array<wallnum_t, 2> front_wallnum; // front wall numbers for this door
std::array<wallnum_t, 2> back_wallnum; // back wall numbers for this door
fix time; // how long been opening, closing, waiting
};
struct d_level_unique_active_door_state
{
active_door_array ActiveDoors;
};
}
namespace dsx {
#if defined(DXX_BUILD_DESCENT_II)
struct cloaking_wall : public prohibit_void_ptr<cloaking_wall>
{
wallnum_t front_wallnum; // front wall numbers for this door
wallnum_t back_wallnum; // back wall numbers for this door
std::array<fix, 4> front_ls; // front wall saved light values
std::array<fix, 4> back_ls; // back wall saved light values
fix time; // how long been cloaking or decloaking
};
struct d_level_unique_cloaking_wall_state
{
cloaking_wall_array CloakingWalls;
};
#endif
struct d_level_unique_wall_state
{
wall_array Walls;
};
struct d_level_unique_wall_subsystem_state :
d_level_unique_active_door_state,
d_level_unique_trigger_state,
d_level_unique_wall_state
#if defined(DXX_BUILD_DESCENT_II)
, d_level_unique_cloaking_wall_state
#endif
{
};
extern d_level_unique_wall_subsystem_state LevelUniqueWallSubsystemState;
struct wclip : public prohibit_void_ptr<wclip>
{
fix play_time;
uint16_t num_frames;
union {
std::array<uint16_t, MAX_CLIP_FRAMES> frames;
std::array<uint16_t, MAX_CLIP_FRAMES_D1> d1_frames;
};
short open_sound;
short close_sound;
short flags;
std::array<char, 13> filename;
};
constexpr std::integral_constant<uint16_t, 0xffff> wclip_frames_none{};
}
#endif