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