SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
BSP.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstddef>
5#include <optional>
6#include <span>
7#include <string>
8#include <tuple>
9#include <vector>
10#include <unordered_map>
11
13
14#include "EntityLump.h"
15#include "LumpData.h"
16#include "PakLump.h"
17
18namespace bsppp {
19
22
23enum class BSPLump : int32_t {
24 UNKNOWN = -1,
105
107};
108constexpr int32_t BSP_LUMP_COUNT = 64;
109static_assert(static_cast<std::underlying_type_t<BSPLump>>(BSPLump::COUNT) == BSP_LUMP_COUNT, "Incorrect lump count!");
110
114constexpr std::array<uint32_t, 64> BSP_LUMP_ORDER{
115 25, 24, 32, 49, 59, 6, 2, 43,
116 44, 10, 17, 1, 18, 19, 14, 5,
117 20, 21, 4, 0, 29, 26, 62, 3,
118 12, 13, 7, 58, 33, 48, 63, 28,
119 9, 8, 53, 37, 38, 39, 30, 31,
120 56, 52, 51, 55, 16, 36, 45, 50,
121 60, 61, 46, 42, 41, 54, 15, 34,
122 47, 11, 22, 23, 27, 35, 40, 57,
123};
124
125class BSP {
126 struct Lump {
128 uint32_t offset;
130 uint32_t length;
132 uint32_t version;
134 uint32_t uncompressedLength;
135 };
136
137 struct Header {
139 uint32_t version;
141 std::array<Lump, BSP_LUMP_COUNT> lumps;
143 uint32_t mapRevision;
144 };
145
146public:
147 explicit BSP(std::string path_, bool loadPatchFiles = true);
148
149 explicit operator bool() const;
150
151 static BSP create(std::string path, uint32_t version = 21, uint32_t mapRevision = 0);
152
153 [[nodiscard]] uint32_t getVersion() const;
154
155 void setVersion(uint32_t version);
156
157 [[nodiscard]] uint32_t getMapRevision() const;
158
159 void setMapRevision(uint32_t mapRevision);
160
161 [[nodiscard]] bool isL4D2() const;
162
163 void setL4D2(bool isL4D2);
164
165 [[nodiscard]] bool isConsole() const;
166
167 void setConsole(bool isConsole);
168
169 [[nodiscard]] bool hasLump(BSPLump lumpIndex) const;
170
171 [[nodiscard]] bool isLumpCompressed(BSPLump lumpIndex) const;
172
173 [[nodiscard]] uint32_t getLumpVersion(BSPLump lumpIndex) const;
174
175 [[nodiscard]] std::optional<std::vector<std::byte>> getLumpData(BSPLump lumpIndex, bool noDecompression = false) const;
176
177 template<BSPLump Lump>
178 [[nodiscard]] auto getLumpData() const {
179 if constexpr (Lump == BSPLump::ENTITIES) {
180 return this->parseEntities();
181 } else if constexpr (Lump == BSPLump::PLANES) {
182 return this->parsePlanes();
183 } else if constexpr (Lump == BSPLump::TEXDATA) {
184 return this->parseTextureData();
185 } else if constexpr (Lump == BSPLump::VERTEXES) {
186 return this->parseVertices();
187 } else if constexpr (Lump == BSPLump::NODES) {
188 return this->parseNodes();
189 } else if constexpr (Lump == BSPLump::TEXINFO) {
190 return this->parseTextureInfo();
191 } else if constexpr (Lump == BSPLump::FACES) {
192 return this->parseFaces();
193 } else if constexpr (Lump == BSPLump::EDGES) {
194 return this->parseEdges();
195 } else if constexpr (Lump == BSPLump::SURFEDGES) {
196 return this->parseSurfEdges();
197 } else if constexpr (Lump == BSPLump::MODELS) {
198 return this->parseBrushModels();
199 } else if constexpr (Lump == BSPLump::ORIGINALFACES) {
200 return this->parseOriginalFaces();
201 } else if constexpr (Lump == BSPLump::GAME_LUMP) {
202 return this->parseGameLumps(true);
203 } else {
204 return this->getLumpData(Lump);
205 }
206 }
207
211 bool setLump(BSPLump lumpIndex, uint32_t version, std::span<const std::byte> data, uint8_t compressLevel = 0);
212
213 bool setLump(uint32_t version, std::span<const BSPEntityKeyValues> data, uint8_t compressLevel = 0);
214
215 [[nodiscard]] bool isGameLumpCompressed(BSPGameLump::Signature signature) const;
216
217 [[nodiscard]] uint16_t getGameLumpVersion(BSPGameLump::Signature signature) const;
218
219 [[nodiscard]] std::optional<std::vector<std::byte>> getGameLumpData(BSPGameLump::Signature signature) const;
220
221 bool setGameLump(BSPGameLump::Signature signature, uint16_t version, std::span<const std::byte> data, uint8_t compressLevel = 0);
222
224 void resetLump(BSPLump lumpIndex);
225
227 void reset();
228
229 void createLumpPatchFile(BSPLump lumpIndex) const;
230
231 bool setLumpFromPatchFile(const std::string& lumpFilePath);
232
233 bool bake(std::string_view outputPath = "");
234
235protected:
236 bool readHeader();
237
238 [[nodiscard]] std::vector<BSPEntityKeyValues> parseEntities() const;
239
240 [[nodiscard]] std::vector<BSPPlane> parsePlanes() const;
241
242 [[nodiscard]] std::vector<BSPTextureData> parseTextureData() const;
243
244 [[nodiscard]] std::vector<BSPVertex> parseVertices() const;
245
246 [[nodiscard]] std::vector<BSPNode> parseNodes() const;
247
248 [[nodiscard]] std::vector<BSPTextureInfo> parseTextureInfo() const;
249
250 [[nodiscard]] std::vector<BSPFace> parseFaces() const;
251
252 [[nodiscard]] std::vector<BSPEdge> parseEdges() const;
253
254 [[nodiscard]] std::vector<BSPSurfEdge> parseSurfEdges() const;
255
256 [[nodiscard]] std::vector<BSPBrushModel> parseBrushModels() const;
257
258 [[nodiscard]] std::vector<BSPFace> parseOriginalFaces() const;
259
260 [[nodiscard]] std::vector<BSPGameLump> parseGameLumps(bool decompress) const;
261
262 std::string path;
263 Header header{};
264
265 uint32_t stagedVersion{};
266 std::unordered_map<uint32_t, std::pair<Lump, std::vector<std::byte>>> stagedLumps;
267 std::vector<BSPGameLump> stagedGameLumps;
269
270 // Slightly different header despite using the same version just to be quirky
271 bool l4d2 = false;
272 // BSP is mostly big-endian
273 bool console = false;
274};
275
276} // namespace bsppp
Header header
Definition BSP.h:263
auto getLumpData() const
Definition BSP.h:178
uint32_t getVersion() const
Definition BSP.cpp:94
bool hasLump(BSPLump lumpIndex) const
Definition BSP.cpp:126
std::vector< BSPBrushModel > parseBrushModels() const
Definition BSP.cpp:708
bool console
Definition BSP.h:273
std::vector< BSPNode > parseNodes() const
Definition BSP.cpp:670
std::vector< BSPTextureData > parseTextureData() const
Definition BSP.cpp:662
std::vector< BSPGameLump > parseGameLumps(bool decompress) const
Definition BSP.cpp:723
std::unordered_map< uint32_t, std::pair< Lump, std::vector< std::byte > > > stagedLumps
Definition BSP.h:266
std::vector< BSPFace > parseOriginalFaces() const
Definition BSP.cpp:712
void setL4D2(bool isL4D2)
Definition BSP.cpp:114
static BSP create(std::string path, uint32_t version=21, uint32_t mapRevision=0)
Definition BSP.cpp:75
bool isLumpCompressed(BSPLump lumpIndex) const
Definition BSP.cpp:135
uint32_t stagedVersion
Definition BSP.h:265
void reset()
Resets ALL in-memory modifications (version, all lumps including game lumps, map revision)
Definition BSP.cpp:295
void setConsole(bool isConsole)
Definition BSP.cpp:122
bool bake(std::string_view outputPath="")
Definition BSP.cpp:365
void resetLump(BSPLump lumpIndex)
Reset changes made to a lump before they're written to disk.
Definition BSP.cpp:277
uint32_t getMapRevision() const
Definition BSP.cpp:102
std::vector< BSPGameLump > stagedGameLumps
Definition BSP.h:267
bool setGameLump(BSPGameLump::Signature signature, uint16_t version, std::span< const std::byte > data, uint8_t compressLevel=0)
Definition BSP.cpp:254
std::vector< BSPFace > parseFaces() const
Definition BSP.cpp:684
uint32_t stagedMapRevision
Definition BSP.h:268
BSP(std::string path_, bool loadPatchFiles=true)
Definition BSP.cpp:46
void setVersion(uint32_t version)
Definition BSP.cpp:98
std::vector< BSPSurfEdge > parseSurfEdges() const
Definition BSP.cpp:704
std::optional< std::vector< std::byte > > getGameLumpData(BSPGameLump::Signature signature) const
Definition BSP.cpp:242
bool isL4D2() const
Definition BSP.cpp:110
std::vector< BSPEdge > parseEdges() const
Definition BSP.cpp:694
std::vector< BSPVertex > parseVertices() const
Definition BSP.cpp:666
void createLumpPatchFile(BSPLump lumpIndex) const
Definition BSP.cpp:305
bool readHeader()
Definition BSP.cpp:539
uint16_t getGameLumpVersion(BSPGameLump::Signature signature) const
Definition BSP.cpp:233
uint32_t getLumpVersion(BSPLump lumpIndex) const
Definition BSP.cpp:143
bool isGameLumpCompressed(BSPGameLump::Signature signature) const
Definition BSP.cpp:224
bool l4d2
Definition BSP.h:271
std::vector< BSPPlane > parsePlanes() const
Definition BSP.cpp:658
bool setLumpFromPatchFile(const std::string &lumpFilePath)
Definition BSP.cpp:343
std::string path
Definition BSP.h:262
bool setLump(BSPLump lumpIndex, uint32_t version, std::span< const std::byte > data, uint8_t compressLevel=0)
BSP::setGameLump should be used for writing game lumps as they need special handling.
Definition BSP.cpp:177
bool isConsole() const
Definition BSP.cpp:118
std::vector< BSPTextureInfo > parseTextureInfo() const
Definition BSP.cpp:680
std::vector< BSPEntityKeyValues > parseEntities() const
Definition BSP.cpp:591
void setMapRevision(uint32_t mapRevision)
Definition BSP.cpp:106
Definition BSP.h:18
constexpr std::array< uint32_t, 64 > BSP_LUMP_ORDER
Pulled from Portal 2, map e1912.
Definition BSP.h:114
constexpr auto BSP_SIGNATURE
Definition BSP.h:20
constexpr int32_t BSP_LUMP_COUNT
Definition BSP.h:108
BSPLump
Definition BSP.h:23
@ ORIGINALFACES
Definition BSP.h:60
@ SL4D2_PROPHULLVERTS
Definition BSP.h:55
@ LEAF_AMBIENT_LIGHTING_HDR
Definition BSP.h:93
@ OVERLAY_FADES
Definition BSP.h:98
@ XBOX_XZIPPAKFILE
Definition BSP.h:95
@ MAP_FLAGS
Definition BSP.h:97
@ PHYSCOLLIDE
Definition BSP.h:62
@ LEAF_AMBIENT_LIGHTING
Definition BSP.h:94
@ PRIMITIVES
Definition BSP.h:71
@ S2006_XBOX_LIGHTMAPPAGES
Definition BSP.h:87
@ L4D_OVERLAY_SYSTEM_LEVELS
Definition BSP.h:99
@ TEXDATA_STRING_DATA
Definition BSP.h:77
@ L4D2_PHYSLEVEL
Definition BSP.h:101
@ LIGHTING_HDR
Definition BSP.h:91
@ VERTNORMALINDICES
Definition BSP.h:64
@ S2004_CLUSTERPORTALS
Definition BSP.h:56
@ LEAF_AMBIENT_INDEX
Definition BSP.h:90
@ LEAFBRUSHES
Definition BSP.h:42
@ FACES_HDR
Definition BSP.h:96
@ ASW_DISP_MULTIBLEND
Definition BSP.h:103
@ S2006_XBOX_LIGHTMAPPAGEINFOS
Definition BSP.h:89
@ AREAPORTALS
Definition BSP.h:46
@ WATEROVERLAYS
Definition BSP.h:86
@ SL4D2_PROPTRIS
Definition BSP.h:58
@ S2004_PORTALVERTS
Definition BSP.h:53
@ LEAFMINDISTTOWATER
Definition BSP.h:80
@ S2004_PORTALS
Definition BSP.h:47
@ LEAFFACES
Definition BSP.h:41
@ CLIPPORTALVERTS
Definition BSP.h:75
@ OCCLUSION
Definition BSP.h:34
@ TEXDATA_STRING_TABLE
Definition BSP.h:78
@ WORLDLIGHTS
Definition BSP.h:40
@ LEAF_AMBIENT_INDEX_HDR
Definition BSP.h:88
@ S2004_CLUSTERS
Definition BSP.h:50
@ SL4D2_PROPHULLS
Definition BSP.h:52
@ DISP_VERTS
Definition BSP.h:67
@ S2004_DISP_LIGHTMAP_ALPHAS
Definition BSP.h:65
@ DISP_TRIS
Definition BSP.h:82
@ LEAFWATERDATA
Definition BSP.h:70
@ PRIMINDICES
Definition BSP.h:73
@ VISIBILITY
Definition BSP.h:29
@ PRIMVERTS
Definition BSP.h:72
@ BRUSHSIDES
Definition BSP.h:44
@ SL4D2_PROP_BLOB
Definition BSP.h:85
@ DISP_LIGHTMAP_SAMPLE_POSITIONS
Definition BSP.h:68
@ VERTNORMALS
Definition BSP.h:63
@ S2004_PHYSCOLLIDESURFACE
Definition BSP.h:83
@ SL4D2_PROPCOLLISION
Definition BSP.h:49
@ FACE_MACRO_TEXTURE_INFO
Definition BSP.h:81
@ GAME_LUMP
Definition BSP.h:69
@ SURFEDGES
Definition BSP.h:38
@ WORLDLIGHTS_HDR
Definition BSP.h:92
constexpr auto BSP_CONSOLE_SIGNATURE
Definition BSP.h:21
consteval uint32_t makeFourCC(const char fourCC[4])
Creates a FourCC identifier from a string of 4 characters.
Definition Binary.h:20