1 /* 2 * Portions of this file are copyright Rebirth contributors and licensed as 3 * described in COPYING.txt. 4 * Portions of this file are copyright Parallax Software and licensed 5 * according to the Parallax license below. 6 * See COPYING.txt for license details. 7 8 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX 9 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO 10 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A 11 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS 12 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS 13 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE 14 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE 15 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS 16 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. 17 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. 18 */ 19 20 /* 21 * 22 * Header for wall.c 23 * 24 */ 25 26 #pragma once 27 28 #include "dsx-ns.h" 29 #include "fwd-segment.h" 30 #include "fwd-wall.h" 31 #include "fwd-object.h" 32 #include "pack.h" 33 #include "switch.h" 34 #include "d_underlying_value.h" 35 36 namespace dcx { 37 38 enum class wall_key : uint8_t 39 { 40 none = 1, 41 blue = 2, 42 red = 4, 43 gold = 8, 44 }; 45 46 constexpr uint8_t operator&(const wall_key a, const wall_key b) 47 { 48 return underlying_value(a) & underlying_value(b); 49 } 50 51 #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) 52 struct WALL_IS_DOORWAY_mask_t 53 { 54 uint8_t value; WALL_IS_DOORWAY_mask_tWALL_IS_DOORWAY_mask_t55 constexpr WALL_IS_DOORWAY_mask_t(WALL_IS_DOORWAY_FLAG F) : 56 value(static_cast<uint8_t>(F)) 57 { 58 } 59 }; 60 61 struct WALL_IS_DOORWAY_result_t 62 { 63 uint8_t value; WALL_IS_DOORWAY_result_tWALL_IS_DOORWAY_result_t64 constexpr WALL_IS_DOORWAY_result_t(const WALL_IS_DOORWAY_sresult_t f) : 65 value(static_cast<unsigned>(f)) 66 { 67 } 68 unsigned operator&(WALL_IS_DOORWAY_FLAG f) const 69 { 70 return value & static_cast<uint8_t>(f); 71 } 72 WALL_IS_DOORWAY_result_t &operator|=(WALL_IS_DOORWAY_FLAG f) 73 { 74 value |= static_cast<uint8_t>(f); 75 return *this; 76 } 77 bool operator==(WALL_IS_DOORWAY_sresult_t F) const 78 { 79 return value == static_cast<unsigned>(F); 80 } 81 bool operator&(WALL_IS_DOORWAY_mask_t m) const 82 { 83 return value & m.value; 84 } 85 bool operator==(WALL_IS_DOORWAY_result_t) const = delete; 86 template <typename T> 87 bool operator!=(const T &t) const 88 { 89 return !(*this == t); 90 } 91 }; 92 93 struct stuckobj : public prohibit_void_ptr<stuckobj> 94 { 95 objnum_t objnum = object_none; 96 wallnum_t wallnum = wall_none; 97 }; 98 #endif 99 100 //Start old wall structures 101 102 struct v16_wall : public prohibit_void_ptr<v16_wall> 103 { 104 sbyte type; // What kind of special wall. 105 sbyte flags; // Flags for the wall. 106 uint8_t trigger; // Which trigger is associated with the wall. 107 fix hps; // "Hit points" of the wall. 108 sbyte clip_num; // Which animation associated with the wall. 109 sbyte keys; 110 }; 111 112 struct v19_wall : public prohibit_void_ptr<v19_wall> 113 { 114 segnum_t segnum; 115 sbyte type; // What kind of special wall. 116 sbyte flags; // Flags for the wall. 117 int sidenum; // Seg & side for this wall 118 fix hps; // "Hit points" of the wall. 119 uint8_t trigger; // Which trigger is associated with the wall. 120 sbyte clip_num; // Which animation associated with the wall. 121 sbyte keys; 122 wallnum_t linked_wall; // number of linked wall 123 }; 124 125 #ifdef dsx 126 class d_level_unique_stuck_object_state 127 { 128 protected: 129 unsigned Num_stuck_objects = 0; 130 std::array<stuckobj, 32> Stuck_objects; 131 public: 132 void init_stuck_objects(); 133 }; 134 #endif 135 136 enum class wall_flag : uint8_t 137 { 138 blasted = 1, // Blasted out wall. 139 door_opened = 1u << 1, // Open door. 140 door_locked = 1u << 3, // Door is locked. 141 door_auto = 1u << 4, // Door automatically closes after time. 142 illusion_off = 1u << 5, // Illusionary wall is shut off. 143 exploding = 1u << 6, 144 #if defined(DXX_BUILD_DESCENT_II) 145 buddy_proof = 1u << 7, // Buddy assumes he cannot get through this wall. 146 #endif 147 }; 148 149 enum class wall_flags : uint8_t; 150 151 enum class wall_state : uint8_t 152 { 153 closed, // Door is closed 154 opening, // Door is opening. 155 waiting, // Waiting to close 156 closing, // Door is closing 157 /* if DXX_BUILD_DESCENT_II */ 158 open, // Door is open, and staying open 159 cloaking, // Wall is going from closed -> open 160 decloaking, // Wall is going from open -> closed 161 /* endif */ 162 }; 163 164 static constexpr auto &operator|=(wall_flags &wall, const wall_flag f) 165 { 166 return wall = static_cast<wall_flags>(underlying_value(wall) | underlying_value(f)); 167 } 168 169 static constexpr auto &operator&=(wall_flags &wall, const wall_flag f) 170 { 171 return wall = static_cast<wall_flags>(underlying_value(wall) & underlying_value(f)); 172 } 173 174 static constexpr auto operator~(const wall_flag f) 175 { 176 return static_cast<wall_flag>(~underlying_value(f)); 177 } 178 179 static constexpr auto operator&(const wall_flags wall, const wall_flag f) 180 { 181 return underlying_value(wall) & underlying_value(f); 182 } 183 184 static constexpr auto operator|(const wall_flag f1, const wall_flag f2) 185 { 186 return static_cast<wall_flag>(underlying_value(f1) | underlying_value(f2)); 187 } 188 189 } 190 191 //End old wall structures 192 193 #ifdef dsx 194 namespace dsx { 195 196 /* No shared state is possible for this structure, but include the 197 * `unique` qualifier to document its status. 198 */ 199 class d_level_unique_stuck_object_state : public ::dcx::d_level_unique_stuck_object_state 200 { 201 public: 202 void add_stuck_object(fvcwallptr &, vmobjptridx_t objp, const shared_segment &segp, unsigned sidenum); 203 void remove_stuck_object(vcobjidx_t); 204 void kill_stuck_objects(fvmobjptr &, vcwallidx_t wallnum); 205 }; 206 207 extern d_level_unique_stuck_object_state LevelUniqueStuckObjectState; 208 209 struct wall : public prohibit_void_ptr<wall> 210 { 211 segnum_t segnum; 212 uint8_t sidenum; // Seg & side for this wall 213 uint8_t type; // What kind of special wall. 214 fix hps; // "Hit points" of the wall. 215 uint16_t explode_time_elapsed; 216 wallnum_t linked_wall; // number of linked wall 217 wall_flags flags; // Flags for the wall. 218 wall_state state; // Opening, closing, etc. 219 trgnum_t trigger; // Which trigger is associated with the wall. 220 sbyte clip_num; // Which animation associated with the wall. 221 wall_key keys; // which keys are required 222 #if defined(DXX_BUILD_DESCENT_II) 223 trgnum_t controlling_trigger;// which trigger causes something to happen here. Not like "trigger" above, which is the trigger on this wall. 224 // Note: This gets stuffed at load time in gamemine.c. Don't try to use it in the editor. You will be sorry! 225 sbyte cloak_value; // if this wall is cloaked, the fade value 226 #endif 227 }; 228 229 } 230 231 namespace dcx { 232 233 struct active_door : public prohibit_void_ptr<active_door> 234 { 235 unsigned n_parts; // for linked walls 236 std::array<wallnum_t, 2> front_wallnum; // front wall numbers for this door 237 std::array<wallnum_t, 2> back_wallnum; // back wall numbers for this door 238 fix time; // how long been opening, closing, waiting 239 }; 240 241 struct d_level_unique_active_door_state 242 { 243 active_door_array ActiveDoors; 244 }; 245 246 } 247 248 namespace dsx { 249 #if defined(DXX_BUILD_DESCENT_II) 250 struct cloaking_wall : public prohibit_void_ptr<cloaking_wall> 251 { 252 wallnum_t front_wallnum; // front wall numbers for this door 253 wallnum_t back_wallnum; // back wall numbers for this door 254 std::array<fix, 4> front_ls; // front wall saved light values 255 std::array<fix, 4> back_ls; // back wall saved light values 256 fix time; // how long been cloaking or decloaking 257 }; 258 259 struct d_level_unique_cloaking_wall_state 260 { 261 cloaking_wall_array CloakingWalls; 262 }; 263 #endif 264 265 struct d_level_unique_wall_state 266 { 267 wall_array Walls; 268 }; 269 270 struct d_level_unique_wall_subsystem_state : 271 d_level_unique_active_door_state, 272 d_level_unique_trigger_state, 273 d_level_unique_wall_state 274 #if defined(DXX_BUILD_DESCENT_II) 275 , d_level_unique_cloaking_wall_state 276 #endif 277 { 278 }; 279 280 extern d_level_unique_wall_subsystem_state LevelUniqueWallSubsystemState; 281 282 struct wclip : public prohibit_void_ptr<wclip> 283 { 284 fix play_time; 285 uint16_t num_frames; 286 union { 287 std::array<uint16_t, MAX_CLIP_FRAMES> frames; 288 std::array<uint16_t, MAX_CLIP_FRAMES_D1> d1_frames; 289 }; 290 short open_sound; 291 short close_sound; 292 short flags; 293 std::array<char, 13> filename; 294 }; 295 296 constexpr std::integral_constant<uint16_t, 0xffff> wclip_frames_none{}; 297 298 } 299 #endif 300