Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
Changes since ELFBSP 1.2
========================

New features:
* Added simple performance profiler, benchmarking the time needed for certain parts of the code to finish work.
* Added support for the brand new XBM1 32-bit blockmap lump format.
* Added support for the Doom 64 binary map format, and its `LEAFS` lump.
165 changes: 165 additions & 0 deletions src/bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,30 @@ static void PutVertices_Doom(level_t &level)
}
}

static void PutVertices_Doom64(level_t &level)
{
// this size is worst-case scenario
size_t size = level.vertices.size() * sizeof(raw_vertex_doom64_t);
Lump_c *lump = CreateLevelLump(level, "VERTEXES", size);

for (size_t i = 0; i < level.vertices.size(); i++)
{
raw_vertex_doom64_t raw;

const vertex_t *vert = level.vertices[i];

// do not ignore vertex_t::is_new
// it is required for leafs

raw.x = GetLittleEndian(FloatToFixed(vert->x));
raw.y = GetLittleEndian(FloatToFixed(vert->y));

lump->Write(&raw, sizeof(raw_vertex_doom64_t));
}

lump->Finish();
}

//
// Vanilla format
//
Expand Down Expand Up @@ -279,6 +303,59 @@ static void PutNodes_Vanilla(level_t &level, node_t *root_node)
}
}

static void PutLeafs_Vanilla(level_t &level)
{
Lump_c *lump = CreateLevelLump(level, "LEAFS");
uint16_t actual_seg_index = 0;

for (size_t i = 0; i < level.subsecs.size(); i++)
{
subsec_t *subsec = level.subsecs[i];
seg_t *seg = subsec->seg_list;
size_t seg_count = subsec->seg_count;

lump->Write(&seg_count, sizeof(uint16_t));

if (HAS_BIT(config.debug, DEBUG_BSP))
{
PrintLine(LOG_DEBUG, "[%s] Subsector[%zu] leaf references: %zu", __func__, i, seg_count);
}

if (seg_count < 3)
{
PrintLine(LOG_ERROR, "[%s] Subsector[%zu] has fewer than 3 leaf references", __func__, i);
}

for (size_t j = 0; j < seg_count; j++)
{
// Do not remove minisegs from tree before
// we are able to write all this
raw_leaf_vanilla_t raw;
vertex_t *vert = seg->start;

raw.vertex = GetLittleEndian(IndexToShort(vert->index));
if (seg->linedef)
// if (seg->linedef && !vert->is_new)
{
raw.seg = GetLittleEndian(actual_seg_index);
actual_seg_index++;
}
else
{
raw.seg = NO_INDEX_INT16;
}

lump->Write(&raw, sizeof(raw));
seg = seg->next;

if (HAS_BIT(config.debug, DEBUG_BSP))
{
PrintLine(LOG_DEBUG, "[%s] Segment = %hu Vertex = %hu", __func__, raw.seg, raw.vertex);
}
}
}
}

//
// DeePBSPV4 format
//
Expand Down Expand Up @@ -431,6 +508,59 @@ static void PutNodes_DeePBSPV4(level_t &level, node_t *root_node)
}
}

static void PutLeafs_DeePBSPV4(level_t &level)
{
Lump_c *lump = CreateLevelLump(level, "LEAFS");
uint32_t actual_seg_index = 0;

for (size_t i = 0; i < level.subsecs.size(); i++)
{
subsec_t *subsec = level.subsecs[i];
seg_t *seg = subsec->seg_list;
size_t seg_count = subsec->seg_count;

lump->Write(&seg_count, sizeof(uint32_t));

if (HAS_BIT(config.debug, DEBUG_BSP))
{
PrintLine(LOG_DEBUG, "[%s] Subsector[%zu] leaf references: %zu", __func__, i, seg_count);
}

if (seg_count < 3)
{
PrintLine(LOG_ERROR, "[%s] Subsector[%zu] has fewer than 3 leaf references", __func__, i);
}

for (size_t j = 0; j < seg_count; j++)
{
// Do not remove minisegs from tree before
// we are able to write all this
raw_leaf_deepbspv4_t raw;
vertex_t *vert = seg->start;

raw.vertex = GetLittleEndian(IndexToShort(vert->index));
if (seg->linedef)
// if (seg->linedef && !vert->is_new)
{
raw.seg = GetLittleEndian(actual_seg_index);
actual_seg_index++;
}
else
{
raw.seg = NO_INDEX_INT32;
}

lump->Write(&raw, sizeof(raw));
seg = seg->next;

if (HAS_BIT(config.debug, DEBUG_BSP))
{
PrintLine(LOG_DEBUG, "[%s] Segment = %u Vertex = %u", __func__, raw.seg, raw.vertex);
}
}
}
}

//
// ZDoom format -- XNOD
//
Expand Down Expand Up @@ -910,6 +1040,41 @@ void SaveDoom_XGL3(level_t &level, node_t *root_node)
CreateLevelLump(level, "NODES")->Finish();
}

//
// Doom64 has some differences from Doom-format or Hexen-format
// This could also be shared with PSX Doom and PSX Final Doom, but we don't support those
//

void SaveDoom64_DoomBSP(level_t &level, node_t *root_node)
{
// Needed for LEAFS
RoundOffVertices(level);
PutVertices_Doom64(level);
// We need minisegs just for leafs
PutLeafs_Vanilla(level);
// remove all the minisegs from subsectors
NormaliseBspTree(level);
SortSegs(level);
PutSegs_Vanilla(level);
PutSubsecs_Vanilla(level);
PutNodes_Vanilla(level, root_node);
}

void SaveDoom64_DeePBSPV4(level_t &level, node_t *root_node)
{
// Needed for LEAFS
RoundOffVertices(level);
PutVertices_Doom64(level);
// We need minisegs just for leafs
PutLeafs_DeePBSPV4(level);
// remove all the minisegs from subsectors
NormaliseBspTree(level);
SortSegs(level);
PutSegs_DeePBSPV4(level);
PutSubsecs_DeePBSPV4(level);
PutNodes_DeePBSPV4(level, root_node);
}

//
// Unlike the the Doom and Hexen map formats, UDMF has a tight requirement for fractional coordinates.
// Always use the latest high-precision BSP format we support.
Expand Down
110 changes: 110 additions & 0 deletions src/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ using map_format_t = enum map_format_e

MapFormat_Doom,
MapFormat_Hexen,
MapFormat_Doom64,
MapFormat_UDMF,
};

Expand All @@ -656,6 +657,11 @@ using lump_order_t = enum lump_order_e
LL_BEHAVIOR, // ACS bytecode
LL_SCRIPTS, // ACS source code

D64_LEAFS = LL_BLOCKMAP + 1, // PSX/N64 hardware rendering
D64_LIGHTS, // Colored sectors
D64_MACROS, // BLAM
D64_SCRIPTS, // BLAM

LL_TEXTMAP = LL_LABEL + 1, // UDMF geometry
LL_ENDMAP, // UDMF end marker

Expand Down Expand Up @@ -748,6 +754,59 @@ using raw_thing_hexen_t = struct raw_thing_hexen_s
uint8_t args[5]; // special arguments
} PACKEDATTR;

// -Elf- Doom64 definitions
// Some are shared with PSX Doom's and PSX Final Doom's formats
// but we don't support those

using raw_vertex_doom64_t = struct raw_vertex_doom64_s
{
fixed_t x;
fixed_t y;
} PACKEDATTR;

using raw_thing_doom64_t = struct raw_thing_doom64_s
{
int16_t x; // x position of thing
int16_t y; // y position of thing
int16_t z; // y position of thing
int16_t angle; // angle thing faces (degrees)
int16_t type; // type of thing
uint16_t options; // when appears, deaf, etc..
} PACKEDATTR;

using raw_linedef_doom64_t = struct raw_linedef_doom64_s
{
uint16_t start; // from this vertex...
uint16_t end; // ... to this vertex
uint32_t flags; // linedef flags (impassible, etc)
uint16_t special; // special type
uint16_t tag; // this linedef activates the sector with same tag
uint16_t right; // right sidedef
uint16_t left; // left sidedef (only if this line adjoins 2 sectors)
} PACKEDATTR;

using raw_sidedef_doom64_t = struct raw_sidedef_doom64_s
{
int16_t x_offset; // X offset for texture
int16_t y_offset; // Y offset for texture
uint16_t upper_tex; // texture index for the part above
uint16_t lower_tex; // texture index for the part below
uint16_t mid_tex; // texture index for the regular part
uint16_t sector; // adjacent sector
} PACKEDATTR;

using raw_sector_doom64_t = struct raw_sector_doom64_s
{
int16_t floorh; // floor height
int16_t ceilh; // ceiling height
uint16_t floor_tex; // floor texture
uint16_t ceil_tex; // ceiling texture
uint16_t colors[5]; // hardware rendering colors, LIGHTS
uint16_t special; // special type
uint16_t tag; // tag number
uint16_t flags; // reverb, damage, water, etc
};

//------------------------------------------------------------------------
// BSP TREE STRUCTURES
//------------------------------------------------------------------------
Expand Down Expand Up @@ -877,6 +936,12 @@ using raw_seg_vanilla_t = struct raw_seg_vanilla_s
int16_t dist; // distance from starting point
} PACKEDATTR;

using raw_leaf_vanilla_t = struct raw_leaf_vanilla_s
{
uint16_t vertex;
uint16_t seg;
} PACKEDATTR;

//
// DeepSea BSP
// * compared to vanilla, some types were raise to 32bit
Expand Down Expand Up @@ -905,6 +970,12 @@ using raw_seg_deepbspv4_t = struct raw_seg_deepbspv4_s
int16_t dist; // distance from starting point
} PACKEDATTR;

using raw_leaf_deepbspv4_t = struct raw_leaf_deepbspv4_s
{
uint32_t vertex;
uint32_t seg;
} PACKEDATTR;

//
// ZDoom BSP
// * compared to vanilla, some types were raise to 32bit
Expand Down Expand Up @@ -1103,6 +1174,43 @@ using lineflag_hexen_t = enum lineflag_hexen_e : uint16_t
MLF_HEXEN_BLOCKEVERYTHING = BIT(15),
};

// See https://www.doom64.com/maps/linedefs.html
using lineflag_doom64_t = enum lineflag_doom64_e : uint32_t
{
MLF_DOOM64_BLOCKING = MLF_BLOCKING,
MLF_DOOM64_BLOCKMONSTERS = MLF_BLOCKMONSTERS,
MLF_DOOM64_TWOSIDED = MLF_TWOSIDED,
MLF_DOOM64_UPPERUNPEGGED = MLF_UPPERUNPEGGED,
MLF_DOOM64_LOWERUNPEGGED = MLF_LOWERUNPEGGED,
MLF_DOOM64_AUTOMAP_ONESIDED = BIT(5),
MLF_DOOM64_BLOCKSOUND = BIT(6),
MLF_DOOM64_AUTOMAP_HIDE = BIT(7),
MLF_DOOM64_AUTOMAP_SHOW = BIT(8),
MLF_DOOM64_RENDER_MIDTEX = BIT(9),
MLF_DOOM64_NO_OCCLUSION = BIT(10),
MLF_DOOM64_BLOCKPROJ = BIT(11),
MLF_DOOM64_DEAD_TRIGGER = BIT(12),
MLF_DOOM64_DECAL_UPPER = BIT(13),
MLF_DOOM64_DECAL_LOWER = BIT(14),
MLF_DOOM64_SWITCH_UPPER = BIT(15),
MLF_DOOM64_SWITCH_LOWER = BIT(16),
MLF_DOOM64_SCROLL_LEFT = BIT(17),
MLF_DOOM64_SCROLL_RIGHT = BIT(18),
MLF_DOOM64_SCROLL_UP = BIT(19),
MLF_DOOM64_SCROLL_DOWN = BIT(20),
MLF_DOOM64_PEG_COLOR_UPPER = BIT(21),
MLF_DOOM64_PEG_COLOR_LOWER = BIT(22),
MLF_DOOM64_UPPER_WALL_COLOR_BLEND = BIT(23),
MLF_DOOM64_TRIGGER_FRONT = BIT(24),
MLF_DOOM64_AUTOMAP_HIDE_SPECIAL = BIT(25),
MLF_DOOM64_FLIP_UPPER_PEGGED_COLOR = BIT(26),
MLF_DOOM64EXPLUS_BLOCKPLAYER = BIT(27),
MLF_DOOM64_UNUSED_28 = BIT(28),
MLF_DOOM64_UNUSED_29 = BIT(29),
MLF_DOOM64_MIRROR_HORI = BIT(30),
MLF_DOOM64_MIRROR_VERT = BIT(31),
};

using hexen_activation_t = enum hexen_activation_e
{
SPAC_Cross = 0, // when line is crossed (W1 / WR)
Expand Down Expand Up @@ -1514,6 +1622,8 @@ struct Lump_c
{
l_start = 0;
}

parent->FinishLump(l_length);
}
};

Expand Down
Loading
Loading