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. 6 * See COPYING.txt for license details. 7 */ 8 9 #pragma once 10 11 #include <type_traits> 12 #include <physfs.h> 13 #include "maths.h" 14 15 #include <cstdint> 16 #include "cpp-valptridx.h" 17 18 namespace dcx { 19 constexpr std::integral_constant<std::size_t, 9000> MAX_SEGMENTS{}; 20 using segnum_t = uint16_t; 21 struct d_level_unique_automap_state; 22 } 23 #ifdef dsx 24 namespace dcx { 25 struct shared_segment; 26 struct unique_segment; 27 struct segment; 28 29 template <typename S, typename U> 30 struct susegment; 31 32 using msmusegment = susegment<shared_segment, unique_segment>; 33 using mscusegment = susegment<shared_segment, const unique_segment>; /* unusual, but supported */ 34 using csmusegment = susegment<const shared_segment, unique_segment>; 35 using cscusegment = susegment<const shared_segment, const unique_segment>; 36 } 37 DXX_VALPTRIDX_DECLARE_SUBTYPE(dcx::, segment, segnum_t, MAX_SEGMENTS); 38 #endif 39 40 #include "fwd-valptridx.h" 41 #include "dsx-ns.h" 42 #include <array> 43 44 namespace dcx { 45 constexpr std::integral_constant<std::size_t, 8> MAX_VERTICES_PER_SEGMENT{}; 46 constexpr std::integral_constant<std::size_t, 6> MAX_SIDES_PER_SEGMENT{}; 47 constexpr std::integral_constant<std::size_t, 4> MAX_VERTICES_PER_POLY{}; 48 49 constexpr std::size_t MAX_SEGMENTS_ORIGINAL = 900; 50 constexpr std::integral_constant<std::size_t, 4 * MAX_SEGMENTS_ORIGINAL> MAX_SEGMENT_VERTICES_ORIGINAL{}; 51 constexpr std::integral_constant<std::size_t, 4 * MAX_SEGMENTS> MAX_SEGMENT_VERTICES{}; 52 53 #ifdef dsx 54 DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(segment, seg); 55 56 static constexpr valptridx<segment>::magic_constant<0xfffe> segment_exit{}; 57 static constexpr valptridx<segment>::magic_constant<0xffff> segment_none{}; 58 static constexpr valptridx<segment>::magic_constant<0> segment_first{}; 59 #endif 60 } 61 #ifdef dsx 62 namespace dsx { 63 void delete_segment_from_group(vmsegptridx_t segment_num, unsigned group_num); 64 } 65 #endif 66 67 namespace dcx { 68 69 enum class materialization_center_number : uint8_t; 70 enum class station_number : uint8_t; 71 72 typedef uint_fast32_t sidenum_fast_t; 73 74 enum sidenum_t : uint8_t 75 { 76 WLEFT = 0, 77 WTOP = 1, 78 WRIGHT = 2, 79 WBOTTOM = 3, 80 WBACK = 4, 81 WFRONT = 5 82 }; 83 84 using texture_index = uint16_t; 85 enum class texture1_value : uint16_t; 86 enum class texture2_value : uint16_t; 87 enum class texture2_rotation_low : uint8_t; 88 enum class texture2_rotation_high : uint16_t; 89 90 //normal everyday vertices 91 92 constexpr std::integral_constant<fix, 0> DEFAULT_LIGHTING{}; // (F1_0/2) 93 94 #if DXX_USE_EDITOR //verts for the new segment 95 constexpr std::integral_constant<std::size_t, 8> NUM_NEW_SEG_VERTICES{}; 96 constexpr std::integral_constant<unsigned, MAX_SEGMENT_VERTICES> NEW_SEGMENT_VERTICES{}; 97 constexpr std::integral_constant<std::size_t, MAX_SEGMENT_VERTICES + NUM_NEW_SEG_VERTICES> MAX_VERTICES{}; 98 #else //No editor 99 constexpr std::integral_constant<std::size_t, MAX_SEGMENT_VERTICES> MAX_VERTICES{}; 100 #endif 101 102 struct uvl; 103 enum class side_type : uint8_t; 104 105 enum class wallnum_t : uint16_t; 106 struct shared_side; 107 struct unique_side; 108 109 struct vertex; 110 enum class vertnum_t : uint32_t; 111 enum class segment_special : uint8_t; 112 } 113 114 /* `vertex` has only integer members, so wild reads are unlikely to 115 * cause serious harm. It is read far more than it is written, so 116 * eliminating checking on reads saves substantial code space. 117 * 118 * Vertex indices are only taken from map data, not network data, so 119 * errors are unlikely. Report them tersely to avoid recording the 120 * file+line of every access. 121 */ 122 #define DXX_VALPTRIDX_REPORT_ERROR_STYLE_const_vertex undefined 123 #define DXX_VALPTRIDX_REPORT_ERROR_STYLE_mutable_vertex trap_terse 124 DXX_VALPTRIDX_DECLARE_SUBTYPE(dcx::, vertex, vertnum_t, MAX_VERTICES); 125 126 #if defined(DXX_BUILD_DESCENT_I) 127 constexpr std::integral_constant<std::size_t, 5> MAX_CENTER_TYPES{}; 128 #elif defined(DXX_BUILD_DESCENT_II) 129 typedef unsigned s2f_ambient_t; 130 constexpr std::integral_constant<s2f_ambient_t, 1> S2F_AMBIENT_WATER{}; 131 constexpr std::integral_constant<s2f_ambient_t, 2> S2F_AMBIENT_LAVA{}; 132 constexpr std::integral_constant<std::size_t, 7> MAX_CENTER_TYPES{}; 133 #endif 134 135 namespace dcx { 136 DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(vertex, vert); 137 struct count_segment_array_t; 138 struct group; 139 140 struct d_level_shared_vertex_state; 141 struct d_level_shared_segment_state; 142 struct d_level_unique_segment_state; 143 144 extern const std::array<std::array<unsigned, 4>, MAX_SIDES_PER_SEGMENT> Side_to_verts; // Side_to_verts[my_side] is list of vertices forming side my_side. 145 extern const std::array<sidenum_t, MAX_SIDES_PER_SEGMENT> Side_opposite; // Side_opposite[my_side] returns side opposite cube from my_side. 146 147 void segment_side_wall_tmap_write(PHYSFS_File *fp, const shared_side &sside, const unique_side &uside); 148 } 149 void add_segment_to_group(segnum_t segment_num, int group_num); 150 151 #if defined(DXX_BUILD_DESCENT_II) 152 namespace dsx { 153 struct delta_light; 154 struct dl_index; 155 struct d_level_shared_destructible_light_state; 156 struct d_level_shared_segment_state; 157 158 constexpr std::integral_constant<std::size_t, 32000> MAX_DELTA_LIGHTS{}; // Original D2: 10000; 159 160 constexpr std::integral_constant<fix, 2048> DL_SCALE{}; // Divide light to allow 3 bits integer, 5 bits fraction. 161 162 using d_delta_light_array = std::array<delta_light, MAX_DELTA_LIGHTS>; 163 164 void clear_light_subtracted(); 165 166 void segment2_write(const cscusegment s2, PHYSFS_File *fp); 167 168 void delta_light_read(delta_light *dl, PHYSFS_File *fp); 169 void delta_light_write(const delta_light *dl, PHYSFS_File *fp); 170 171 void dl_index_read(dl_index *di, PHYSFS_File *fp); 172 void dl_index_write(const dl_index *di, PHYSFS_File *fp); 173 using dlindexnum_t = uint16_t; 174 } 175 #define DXX_VALPTRIDX_REPORT_ERROR_STYLE_default_dl_index trap_terse 176 DXX_VALPTRIDX_DECLARE_SUBTYPE(dsx::, dl_index, ::dsx::dlindexnum_t, 500); 177 namespace dsx { 178 DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(dl_index, dlindex); 179 int subtract_light(const d_level_shared_destructible_light_state &LevelSharedDestructibleLightState, vmsegptridx_t segnum, sidenum_fast_t sidenum); 180 int add_light(const d_level_shared_destructible_light_state &LevelSharedDestructibleLightState, vmsegptridx_t segnum, sidenum_fast_t sidenum); 181 } 182 #endif 183 184 namespace dcx { 185 186 template <unsigned bits> 187 class visited_segment_mask_t; 188 using visited_segment_bitarray_t = visited_segment_mask_t<1>; 189 190 constexpr std::integral_constant<int, MAX_SIDES_PER_SEGMENT> side_none{}; 191 constexpr std::integral_constant<int, -1> edge_none{}; 192 193 } 194