dxx-rebirth/common/main/fwd-segment.h
Kp 6d3dce4e16 Use enum class for tmap_num2
Define separate enum values for rotation data in both the high bits,
where it is usually kept, and the low bits, where it is sometimes used
for math or comparisons.

Define an enum value to represent the composite of the index and the
rotation, since the composite is not suitable for use as an array
subscript.  Add helper functions to extract the component pieces.
2020-08-24 01:31:28 +00:00

193 lines
6.5 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.
* See COPYING.txt for license details.
*/
#pragma once
#include <type_traits>
#include <physfs.h>
#include "maths.h"
#include <cstdint>
#include "cpp-valptridx.h"
namespace dcx {
constexpr std::integral_constant<std::size_t, 9000> MAX_SEGMENTS{};
using segnum_t = uint16_t;
}
#ifdef dsx
namespace dcx {
struct shared_segment;
struct unique_segment;
struct segment;
template <typename S, typename U>
struct susegment;
using msmusegment = susegment<shared_segment, unique_segment>;
using mscusegment = susegment<shared_segment, const unique_segment>; /* unusual, but supported */
using csmusegment = susegment<const shared_segment, unique_segment>;
using cscusegment = susegment<const shared_segment, const unique_segment>;
}
DXX_VALPTRIDX_DECLARE_SUBTYPE(dcx::, segment, segnum_t, MAX_SEGMENTS);
#endif
#include "fwd-valptridx.h"
#include "dsx-ns.h"
#include <array>
namespace dcx {
constexpr std::integral_constant<std::size_t, 8> MAX_VERTICES_PER_SEGMENT{};
constexpr std::integral_constant<std::size_t, 6> MAX_SIDES_PER_SEGMENT{};
constexpr std::integral_constant<std::size_t, 4> MAX_VERTICES_PER_POLY{};
constexpr std::size_t MAX_SEGMENTS_ORIGINAL = 900;
constexpr std::integral_constant<std::size_t, 4 * MAX_SEGMENTS_ORIGINAL> MAX_SEGMENT_VERTICES_ORIGINAL{};
constexpr std::integral_constant<std::size_t, 4 * MAX_SEGMENTS> MAX_SEGMENT_VERTICES{};
}
#ifdef dsx
namespace dsx {
DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(segment, seg);
static constexpr valptridx<segment>::magic_constant<0xfffe> segment_exit{};
static constexpr valptridx<segment>::magic_constant<0xffff> segment_none{};
static constexpr valptridx<segment>::magic_constant<0> segment_first{};
void delete_segment_from_group(vmsegptridx_t segment_num, unsigned group_num);
}
#endif
namespace dcx {
typedef uint_fast32_t sidenum_fast_t;
enum sidenum_t : uint8_t
{
WLEFT = 0,
WTOP = 1,
WRIGHT = 2,
WBOTTOM = 3,
WBACK = 4,
WFRONT = 5
};
enum class texture2_value : uint16_t;
enum class texture2_rotation_low : uint8_t;
enum class texture2_rotation_high : uint16_t;
//normal everyday vertices
constexpr std::integral_constant<fix, 0> DEFAULT_LIGHTING{}; // (F1_0/2)
#if DXX_USE_EDITOR //verts for the new segment
constexpr std::integral_constant<std::size_t, 8> NUM_NEW_SEG_VERTICES{};
constexpr std::integral_constant<unsigned, MAX_SEGMENT_VERTICES> NEW_SEGMENT_VERTICES{};
constexpr std::integral_constant<std::size_t, MAX_SEGMENT_VERTICES + NUM_NEW_SEG_VERTICES> MAX_VERTICES{};
#else //No editor
constexpr std::integral_constant<std::size_t, MAX_SEGMENT_VERTICES> MAX_VERTICES{};
#endif
struct uvl;
enum class side_type : uint8_t;
using wallnum_t = uint16_t;
struct shared_side;
struct unique_side;
struct vertex;
using vertnum_t = uint32_t;
}
/* `vertex` has only integer members, so wild reads are unlikely to
* cause serious harm. It is read far more than it is written, so
* eliminating checking on reads saves substantial code space.
*
* Vertex indices are only taken from map data, not network data, so
* errors are unlikely. Report them tersely to avoid recording the
* file+line of every access.
*/
#define DXX_VALPTRIDX_REPORT_ERROR_STYLE_const_vertex undefined
#define DXX_VALPTRIDX_REPORT_ERROR_STYLE_mutable_vertex trap_terse
DXX_VALPTRIDX_DECLARE_SUBTYPE(dcx::, vertex, vertnum_t, MAX_VERTICES);
typedef unsigned segment_type_t;
constexpr segment_type_t SEGMENT_IS_NOTHING = 0;
constexpr segment_type_t SEGMENT_IS_FUELCEN = 1;
constexpr segment_type_t SEGMENT_IS_REPAIRCEN = 2;
constexpr segment_type_t SEGMENT_IS_CONTROLCEN = 3;
constexpr segment_type_t SEGMENT_IS_ROBOTMAKER = 4;
#if defined(DXX_BUILD_DESCENT_I)
constexpr std::integral_constant<std::size_t, 5> MAX_CENTER_TYPES{};
#elif defined(DXX_BUILD_DESCENT_II)
typedef unsigned s2f_ambient_t;
constexpr std::integral_constant<s2f_ambient_t, 1> S2F_AMBIENT_WATER{};
constexpr std::integral_constant<s2f_ambient_t, 2> S2F_AMBIENT_LAVA{};
constexpr std::integral_constant<std::size_t, 7> MAX_CENTER_TYPES{};
constexpr segment_type_t SEGMENT_IS_GOAL_BLUE = 5;
constexpr segment_type_t SEGMENT_IS_GOAL_RED = 6;
#endif
namespace dcx {
DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(vertex, vert);
struct count_segment_array_t;
struct group;
struct d_level_shared_vertex_state;
struct d_level_shared_segment_state;
struct d_level_unique_segment_state;
#define Side_to_verts Side_to_verts_int
extern const std::array<std::array<unsigned, 4>, MAX_SIDES_PER_SEGMENT> Side_to_verts_int; // Side_to_verts[my_side] is list of vertices forming side my_side.
extern const std::array<uint8_t, MAX_SIDES_PER_SEGMENT> Side_opposite; // Side_opposite[my_side] returns side opposite cube from my_side.
void segment_side_wall_tmap_write(PHYSFS_File *fp, const shared_side &sside, const unique_side &uside);
}
void add_segment_to_group(segnum_t segment_num, int group_num);
#if defined(DXX_BUILD_DESCENT_II)
namespace dsx {
struct delta_light;
struct dl_index;
struct d_level_shared_destructible_light_state;
struct d_level_shared_segment_state;
constexpr std::integral_constant<std::size_t, 32000> MAX_DELTA_LIGHTS{}; // Original D2: 10000;
constexpr std::integral_constant<fix, 2048> DL_SCALE{}; // Divide light to allow 3 bits integer, 5 bits fraction.
using d_delta_light_array = std::array<delta_light, MAX_DELTA_LIGHTS>;
void clear_light_subtracted();
void segment2_write(const cscusegment s2, PHYSFS_File *fp);
void delta_light_read(delta_light *dl, PHYSFS_File *fp);
void delta_light_write(const delta_light *dl, PHYSFS_File *fp);
void dl_index_read(dl_index *di, PHYSFS_File *fp);
void dl_index_write(const dl_index *di, PHYSFS_File *fp);
using dlindexnum_t = uint16_t;
}
#define DXX_VALPTRIDX_REPORT_ERROR_STYLE_default_dl_index trap_terse
DXX_VALPTRIDX_DECLARE_SUBTYPE(dsx::, dl_index, dlindexnum_t, 500);
namespace dsx {
DXX_VALPTRIDX_DEFINE_SUBTYPE_TYPEDEFS(dl_index, dlindex);
int subtract_light(const d_level_shared_destructible_light_state &LevelSharedDestructibleLightState, vmsegptridx_t segnum, sidenum_fast_t sidenum);
int add_light(const d_level_shared_destructible_light_state &LevelSharedDestructibleLightState, vmsegptridx_t segnum, sidenum_fast_t sidenum);
}
#endif
namespace dcx {
template <unsigned bits>
class visited_segment_mask_t;
using visited_segment_bitarray_t = visited_segment_mask_t<1>;
constexpr std::integral_constant<int, MAX_SIDES_PER_SEGMENT> side_none{};
constexpr std::integral_constant<int, -1> edge_none{};
}