17 Commits
1.5.0 ... 1.5.2

Author SHA1 Message Date
Matt Nadareski
0451af3eb4 Bump version 2024-11-18 20:37:56 -05:00
Matt Nadareski
7967eb29eb Move Deflate constants to new file 2024-11-18 12:09:48 -05:00
Matt Nadareski
6bbe904cc3 Move Deflate-specific models to separate namespace 2024-11-18 10:04:45 -05:00
Matt Nadareski
dce9d98885 Add GZIP models 2024-11-18 02:45:07 -05:00
Matt Nadareski
f862e018fb Update VPK models 2024-11-18 02:13:52 -05:00
Matt Nadareski
b4a5154da8 Update VBSP models 2024-11-18 01:59:46 -05:00
Matt Nadareski
077aa3c57e Update BSP models 2024-11-17 21:20:50 -05:00
Matt Nadareski
ea8630ba8c Update WAD3 models 2024-11-17 19:56:59 -05:00
Matt Nadareski
385491c67b Framework only matters for executable 2024-11-15 20:16:03 -05:00
Matt Nadareski
f57461e0c3 Make obsolete types NoWarn instead of ignore 2024-11-15 20:10:16 -05:00
Matt Nadareski
18f49ac43f It was correct 2024-11-14 11:19:21 -05:00
Matt Nadareski
28fd81adab Minor tweaks 2024-11-13 23:12:37 -05:00
Matt Nadareski
ecca68822d Bump version 2024-11-13 20:33:38 -05:00
Matt Nadareski
58c2dcbe4f Fix duplicate data bug in N3DS cart data 2024-11-13 17:03:57 -05:00
Matt Nadareski
f9b8717abb Add .NET 9 to target frameworks 2024-11-13 00:33:49 -05:00
Matt Nadareski
6a356a5874 Add .NET 9 to target frameworks 2024-11-13 00:19:00 -05:00
Matt Nadareski
88c6a0302f Add .NET 9 to target frameworks 2024-11-13 00:16:28 -05:00
137 changed files with 4758 additions and 492 deletions

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class AmbientIndexLump : Lump
{
/// <summary>
/// Indicies
/// </summary>
public LeafAmbientIndex[]? Indicies { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class AmbientLightingLump : Lump
{
/// <summary>
/// Lightings
/// </summary>
public LeafAmbientLighting[]? Lightings { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The brush lump (Lump 18) contains all brushes that were
/// present in the original VMF file before compiling.
/// Unlike faces, brushes are constructive solid geometry (CSG)
/// defined by planes instead of edges and vertices. It is the
/// presence of the brush and brushside lumps in Source BSP
/// files that makes decompiling them a much easier job than
/// for GoldSrc files, which lacked this info.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Brush
{
/// <summary>
/// First brushside
/// </summary>
public int FirstSide;
/// <summary>
/// Number of brushsides
/// </summary>
public int NumSides;
/// <summary>
/// Contents flags
/// </summary>
public VbspContents Contents;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class BrushesLump : Lump
{
/// <summary>
/// Brushes
/// </summary>
public Brush[]? Brushes { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// Planenum is an index info the plane array, giving the plane
/// corresponding to this brushside. Texinfo and dispinfo are
/// references into the texture and displacement info lumps.
/// Bevel is zero for normal brush sides, but 1 if the side is
/// a bevel plane (which seem to be used for collision detection).
///
/// Unlike the face array, brushsides are not culled (removed)
/// where they touch the void. Void-facing sides do however have
/// their texinfo entry changed to the tools/toolsnodraw texture
/// during the compile process. Note there is no direct way of
/// linking brushes and brushsides and the corresponding face array
/// entries which are used to render that brush. Brushsides are
/// used by the engine to calculate all player physics collision
/// with world brushes. (Vphysics objects use lump 29 instead.)
///
/// The maximum number of brushsides is 65536 (MAX_MAP_BRUSHSIDES).
/// The maximum number of brushsides on a single brush is 128 (MAX_BRUSH_SIDES).
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Brushside
{
/// <summary>
/// Facing out of the leaf
/// </summary>
public ushort PlaneNum;
/// <summary>
/// Texture info
/// </summary>
public short TextureInfo;
/// <summary>
/// Displacement info
/// </summary>
public short DisplacementInfo;
/// <summary>
/// Is the side a bevel plane?
/// </summary>
public short Bevel;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class BrushsidesLump : Lump
{
/// <summary>
/// Brushsides
/// </summary>
public Brushside[]? Brushsides { get; set; }
}
}

View File

@@ -0,0 +1,66 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The face lump contains the surfaces of the scene.
///
/// The first number of this data structure is an index into
/// the planes lump giving a plane which is parallel to this
/// face (meaning they share the same normal). The second
/// value may be seen as a boolean. If nPlaneSide equals 0,
/// then the normal vector of this face equals the one of the
/// parallel plane exactly. Otherwise, the normal of the plane
/// has to be multiplied by -1 to point into the right direction.
/// Afterwards we have an index into the surfedges lump, as
/// well as the count of consecutive surfedges from that position.
/// Furthermore there is an index into the texture info lump,
/// which is used to find the BSPTEXINFO structure needed to
/// calculate the texture coordinates for this face. Afterwards,
/// there are four bytes giving some lighting information (partly
/// used by the renderer to hide sky surfaces). Finally we have
/// an offset in byes giving the beginning of the binary lightmap
/// data of this face in the lighting lump.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BspFace
{
/// <summary>
/// Plane the face is parallel to
/// </summary>
public ushort PlaneIndex;
/// <summary>
/// Set if different normals orientation
/// </summary>
public ushort PlaneSideCount;
/// <summary>
/// Index of the first surfedge
/// </summary>
public uint FirstEdgeIndex;
/// <summary>
/// Number of consecutive surfedges
/// </summary>
public ushort NumberOfEdges;
/// <summary>
/// Index of the texture info structure
/// </summary>
public ushort TextureInfoIndex;
/// <summary>
/// Specify lighting styles
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[]? LightingStyles = new byte[4];
/// <summary>
/// Offsets into the raw lightmap data; if less than zero,
/// then a lightmap was not baked for the given face.
/// </summary>
public int LightmapOffset;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class BspFacesLump : Lump
{
/// <summary>
/// Faces
/// </summary>
public BspFace[]? Faces { get; set; }
}
}

View File

@@ -0,0 +1,89 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// Half-Life Level
/// </summary>
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class BspFile
{
/// <summary>
/// Header data
/// </summary>
public BspHeader? Header { get; set; }
#region Lumps
/// <summary>
/// LUMP_ENTITIES [0]
/// </summary>
public EntitiesLump? Entities { get; set; }
/// <summary>
/// LUMP_PLANES [1]
/// </summary>
public PlanesLump? PlanesLump { get; set; }
/// <summary>
/// LUMP_TEXTURES [2]
/// </summary>
public TextureLump? TextureLump { get; set; }
/// <summary>
/// LUMP_VERTICES [3]
/// </summary>
public VerticesLump? VerticesLump { get; set; }
/// <summary>
/// LUMP_NODES [5]
/// </summary>
public BspNodesLump? NodesLump { get; set; }
/// <summary>
/// LUMP_TEXINFO [6]
/// </summary>
public BspTexinfoLump? TexinfoLump { get; set; }
/// <summary>
/// LUMP_FACES [7]
/// </summary>
public BspFacesLump? FacesLump { get; set; }
/// <summary>
/// LUMP_LIGHTING [8]
/// </summary>
public LightmapLump? LightmapLump { get; set; }
/// <summary>
/// LUMP_CLIPNODES [9]
/// </summary>s
public ClipnodesLump? ClipnodesLump { get; set; }
/// <summary>
/// LUMP_LEAVES [10]
/// </summary>
public BspLeavesLump? LeavesLump { get; set; }
/// <summary>
/// LUMP_MARKSURFACES [11]
/// </summary>
public MarksurfacesLump? MarksurfacesLump { get; set; }
/// <summary>
/// LUMP_EDGES [12]
/// </summary>
public EdgesLump? EdgesLump { get; set; }
/// <summary>
/// LUMP_SURFEDGES [13]
/// </summary>
public SurfedgesLump? SurfedgesLump { get; set; }
/// <summary>
/// LUMP_MODELS [14]
/// </summary>
public BspModelsLump? ModelsLump { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,22 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BspHeader
{
/// <summary>
/// Version
/// </summary>
/// <remarks>Must be 30 for a valid HL BSP file</remarks>
public int Version;
/// <summary>
/// Lumps
/// </summary>
/// <remarks>15 entries</remarks>
public BspLumpEntry[]? Lumps { get; set; }
}
}

View File

@@ -0,0 +1,67 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The leaves lump contains the leaves of the BSP tree.
///
/// The first entry of this struct is the type of the content
/// of this leaf. It can be one of the predefined values, found
/// in the compiler source codes, and is litte relevant for the
/// actual rendering process. All the more important is the
/// next integer containing the offset into the vis lump. It
/// defines the start of the raw PVS data for this leaf. If this
/// value equals -1, no VIS lists are available for this leaf,
/// usually if the map has been built without the VIS compiler.
/// The next two 16bit integer triples span the bounding box of
/// this leaf. Furthermore, the struct contains an index pointing
/// into the array of marksurfaces loaded from the marksufaces
/// lump as well as the number of consecutive marksurfaces belonging
/// to this leaf. The marksurfaces are looped through during the
/// rendering process and point to the actual faces. The final 4 bytes
/// specify the volume of ambient sounds in Quake, but are unused in
/// GoldSrc.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BspLeaf
{
/// <summary>
/// Contents enumeration
/// </summary>
public BspContents Contents;
/// <summary>
/// Offset into the visibility lump
/// </summary>
public int VisOffset;
/// <summary>
/// Defines bounding box
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public short[] Mins = new short[3];
/// <summary>
/// Defines bounding box
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public short[] Maxs = new short[3];
/// <summary>
/// Index into marksurfaces array
/// </summary>
public ushort FirstMarkSurfaceIndex;
/// <summary>
/// Count of marksurfaces array
/// </summary>
public ushort MarkSurfacesCount;
/// <summary>
/// Ambient sound levels
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[]? AmbientLevels = new byte[4];
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class BspLeavesLump : Lump
{
/// <summary>
/// Leaves
/// </summary>
public BspLeaf[]? Leaves { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public class BspLumpEntry
{
/// <summary>
/// File offset to data
/// </summary>
public int Offset;
/// <summary>
/// Length of data
/// </summary>
public int Length;
}
}

View File

@@ -0,0 +1,63 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// A model is kind of a mini BSP tree. Its size is determinded
/// by the bounding box spaned by the first to members of this
/// struct. The major difference between a model and the BSP
/// tree holding the scene is that the models use a local
/// coordinate system for their vertexes and just state its
/// origin in world coordinates. During rendering the coordinate
/// system is translated to the origin of the model (glTranslate())
/// and moved back after the models BSP tree has been traversed.
/// Furthermore their are 4 indexes into node arrays. The first
/// one has proofed to index the root node of the mini BSP tree
/// used for rendering. The other three indexes could probably be
/// used for collision detection, meaning they point into the
/// clipnodes, but I am not sure about this. The meaning of the
/// next value is also somehow unclear to me. Finally their are
/// direct indexes into the faces array, not taking the redirecting
/// by the marksurfaces.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BspModel
{
/// <summary>
/// Defines bounding box
/// </summary>
public Vector3D Mins;
/// <summary>
/// Defines bounding box
/// </summary>
public Vector3D Maxs;
/// <summary>
/// Coordinates to move the coordinate system
/// </summary>
public Vector3D OriginVector;
/// <summary>
/// Index into nodes array
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.MAX_MAP_HULLS)]
public int[]? HeadnodesIndex = new int[Constants.MAX_MAP_HULLS];
/// <summary>
/// ???
/// </summary>
public int VisLeafsCount;
/// <summary>
/// Index into faces
/// </summary>
public int FirstFaceIndex;
/// <summary>
/// Count of faces
/// </summary>
public int FacesCount;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class BspModelsLump : Lump
{
/// <summary>
/// Model
/// </summary>
public BspModel[]? Models { get; set; }
}
}

View File

@@ -0,0 +1,62 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// This lump is simple again and contains an array of binary
/// structures, the nodes, which are a major part of the BSP tree.
///
/// Every BSPNODE structure represents a node in the BSP tree and
/// every node equals more or less a division step of the BSP algorithm.
/// Therefore, each node has an index (iPlane) referring to a plane
/// in the plane lump which devides the node into its two child nodes.
/// The childnodes are also stored as indexes. Contrary to the plane
/// index, the node index for the child is signed. If the index is
/// larger than 0, the index indicates a child node. If it is equal
/// to or smaller than zero (no valid array index), the bitwise
/// inversed value of the index gives an index into the leaves lump.
/// Additionally two points (nMins, nMaxs) span the bounding box
/// (AABB, axis aligned bounding box) delimitting the space of the node.
/// Finally firstFace indexes into the face lump and spezifies the
/// first of nFaces surfaces contained in this node.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public class BspNode
{
/// <summary>
/// Index into Planes lump
/// </summary>
public uint PlaneIndex;
/// <summary>
/// If > 0, then indices into Nodes.
/// Otherwise bitwise inverse indices into Leafs
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public ushort[] Children = new ushort[2];
/// <summary>
/// Defines bounding box
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public ushort[] Mins = new ushort[3];
/// <summary>
/// Defines bounding box
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public ushort[] Maxs = new ushort[3];
/// <summary>
/// Index into Faces
/// </summary>
public ushort FirstFace;
/// <summary>
/// Count of Faces
/// </summary>
public ushort FaceCount;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class BspNodesLump : Lump
{
/// <summary>
/// Nodes
/// </summary>
public BspNode[]? Nodes { get; set; }
}
}

View File

@@ -0,0 +1,52 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The texinfo lump contains informations about how textures are
/// applied to surfaces. The lump itself is an array of binary data
/// structures.
///
/// This struct is mainly responsible for the calculation of the texture
/// coordinates (vS, fSShift, vT, fTShift). This values determine the
/// position of the texture on the surface. The iMiptex integer refers
/// to the textures in the texture lump and would be the index in an
/// array of BSPMITEX structs. Finally, there are 4 Bytes used for flags.
/// Only one flag is used by the vanilla engine, being 0x1 for disabling
/// lightmaps and subdivision for the surface (used by sky and liquids).
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BspTexinfo
{
/// <summary>
/// S-vector
/// </summary>
public Vector3D SVector;
/// <summary>
/// Texture shift in the S direction
/// </summary>
public float TextureSShift;
/// <summary>
/// T-vector
/// </summary>
public Vector3D TVector;
/// <summary>
/// Texture shift in the T direction
/// </summary>
public float TextureTShift;
/// <summary>
/// Index into textures array
/// </summary>
public uint MiptexIndex;
/// <summary>
/// Texture flags
/// </summary>
public TextureFlag Flags;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class BspTexinfoLump : Lump
{
/// <summary>
/// Texinfos
/// </summary>
public BspTexinfo[]? Texinfos { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/bspfile.h#L600"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class CDispCornerNeighbors
{
/// <summary>
/// Indices of neighbors.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[] Neighbors = new ushort[4];
public byte NeighborCount;
}
}

View File

@@ -0,0 +1,12 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/bspfile.h#L583"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class CDispNeighbor
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public CDispSubNeighbor[]? SubNeighbors = new CDispSubNeighbor[2];
}
}

View File

@@ -0,0 +1,32 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/bspfile.h#L557"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class CDispSubNeighbor
{
/// <summary>
/// This indexes into ddispinfos.
/// </summary>
/// <remarks>0xFFFF if there is no neighbor here.</remarks>
public ushort NeighborIndex;
/// <summary>
/// (CCW) rotation of the neighbor wrt this displacement.
/// </summary>
public byte NeighborOrientation;
// These use the NeighborSpan type.
/// <summary>
/// Where the neighbor fits onto this side of our displacement.
/// </summary>
public byte Span;
/// <summary>
/// Where we fit onto our neighbor.
/// </summary>
public byte NeighborSpan;
}
}

View File

@@ -0,0 +1,28 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// This lump contains the so-called clipnodes, which build a second
/// BSP tree used only for collision detection.
///
/// This structure is a reduced form of the BSPNODE struct from the
/// nodes lump. Also the BSP tree built by the clipnodes is simpler
/// than the one described by the BSPNODEs to accelerate collision calculations.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Clipnode
{
/// <summary>
/// Index into planes
/// </summary>
public int PlaneIndex;
/// <summary>
/// Negative numbers are contents
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public short[]? ChildrenIndices = new short[2];
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class ClipnodesLump : Lump
{
/// <summary>
/// Clipnodes
/// </summary>
public Clipnode[]? Clipnodes { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// 4-byte lightmap structure
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public struct ColorRGBExp32
{
public byte Red;
public byte Green;
public byte Blue;
public sbyte Exponent;
}
}

View File

@@ -0,0 +1,16 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The lighting data for each sample is represented by an array
/// of 6 ColorRGBExp32
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public struct CompressedLightCube
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public ColorRGBExp32[]? Colors;
}
}

View File

@@ -1,25 +1,100 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public static class Constants
{
#region Header
/// <summary>
/// Number of lumps in a BSP
/// </summary>
public const int HL_BSP_LUMP_COUNT = 15;
public const int BSP_HEADER_LUMPS = 15;
/// <summary>
/// Index for the entities lump
/// Number of lumps in a VBSP
/// </summary>
public const int HL_BSP_LUMP_ENTITIES = 0;
public const int VBSP_HEADER_LUMPS = 64;
#endregion
#region Lump
public const int MAX_MAP_HULLS = 4;
public const int MAX_MAP_MODELS = 400;
public const int MAX_MAP_BRUSHES = 4096;
public const int MAX_MAP_ENTITIES = 1024;
public const int MAX_MAP_ENTSTRING = (128 * 1024);
public const int MAX_MAP_PLANES = 32767;
public const int MAX_MAP_NODES = 32767;
public const int MAX_MAP_CLIPNODES = 32767;
public const int MAX_MAP_LEAFS = 8192;
public const int MAX_MAP_VERTS = 65535;
public const int MAX_MAP_FACES = 65535;
public const int MAX_MAP_MARKSURFACES = 65535;
public const int MAX_MAP_TEXINFO = 8192;
public const int MAX_MAP_EDGES = 256000;
public const int MAX_MAP_SURFEDGES = 512000;
public const int MAX_MAP_TEXTURES = 512;
public const int MAX_MAP_MIPTEX = 0x200000;
public const int MAX_MAP_LIGHTING = 0x200000;
public const int MAX_MAP_VISIBILITY = 0x200000;
public const int MAX_MAP_PORTALS = 65536;
#endregion
#region Entities
public const int MAX_KEY = 32;
public const int MAX_VALUE = 1024;
#endregion
#region Textures
public const int MAXTEXTURENAME = 16;
public const int MIPLEVELS = 4;
#endregion
#region VBSP
public static readonly byte[] SignatureBytes = [0x56, 0x42, 0x53, 0x50];
public const string SignatureString = "VBSP";
public const uint SignatureUInt32 = 0x50534256;
#endregion
#region LZMA
public static readonly byte[] LzmaHeaderBytes = [0x4C, 0x5A, 0x4D, 0x41];
public const string LzmaHeaderString = "LZMA";
public const uint LzmaHeaderUInt32 = 0x414D5A4C;
#endregion
#region Overlay
public const int OVERLAY_BSP_FACE_COUNT = 64;
#endregion
#region Worldlights
/// <summary>
/// Index for the texture data lump
/// This says that the light was put into the per-leaf ambient cubes.
/// </summary>
public const int HL_BSP_LUMP_TEXTUREDATA = 2;
public const int DWL_FLAGS_INAMBIENTCUBE = 0x0001;
/// <summary>
/// Number of valid mipmap levels
/// </summary>
public const int HL_BSP_MIPMAP_COUNT = 4;
#endregion
}
}

View File

@@ -0,0 +1,50 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The dcubemapsample_t structure defines the location of a
/// env_cubemap entity in the map. The origin member contains
/// integer x,y,z coordinates of the cubemap, and the size member
/// is resolution of the cubemap, specified as 2^(size-1) pixels
/// square. If set as 0, the default size of 6 (32x32 pixels) is
/// used. There can be a maximum of 1024 (MAX_MAP_CUBEMAPSAMPLES)
/// cubemaps in a file.
///
/// When the "buildcubemaps" console command is performed, six
/// snapshots of the map (one for each direction) are taken at the
/// location of each env_cubemap entity. These snapshots are stored
/// in a multi-frame texture (vtf) file, which is added to the
/// Pakfile lump (see above). The textures are named cX_Y_Z.vtf,
/// where (X,Y,Z) are the (integer) coordinates of the corresponding
/// cubemap.
///
/// Faces containing materials that are environment mapped (e.g.
/// shiny textures) reference their assigned cubemap through their
/// material name. A face with a material named (e.g.) walls/shiny.vmt
/// is altered (new Texinfo & Texdata entries are created) to refer
/// to a renamed material maps/mapname/walls/shiny_X_Y_Z.vmt, where
/// (X,Y,Z) are the cubemap coordinates as before. This .vmt file
/// is also stored in the Pakfile, and references the cubemap .vtf
/// file through its $envmap property.
///
/// Version 20 files contain extra cX_Y_Z.hdr.vtf files in the
/// Pakfile lump, containing HDR texture files in RGBA16161616F
/// (16-bit per channel) format.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Cubemap
{
/// <summary>
/// Position of light snapped to the nearest integer
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public int[]? Origin = new int[3];
/// <summary>
/// Resolution of cubemap, 0 - default
/// </summary>
public int Size;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class CubemapsLump : Lump
{
/// <summary>
/// Cubemaps
/// </summary>
public Cubemap[]? Cubemaps { get; set; }
}
}

View File

@@ -0,0 +1,93 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The structure is 176 bytes long. The startPosition element is the
/// coordinates of the first corner of the displacement. DispVertStart
/// and DispTriStart are indices into the DispVerts and DispTris lumps.
/// The power entry gives the number of subdivisions in the displacement
/// surface - allowed values are 2, 3 and 4, and these correspond to 4,
/// 8 and 16 subdivisions on each side of the displacement surface.
/// The structure also references any neighbouring displacements on the
/// sides or the corners of this displacement through the EdgeNeighbors
/// and CornerNeighbors members. There are complex rules governing the
/// order that these neighbour displacements are given; see the comments
/// in bspfile.h for more. The MapFace value is an index into the face
/// array and is face that was turned into a displacement surface.
/// This face is used to set the texture and overall physical location
/// and boundaries of the displacement.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DispInfo
{
/// <summary>
/// Start position used for orientation
/// </summary>
public Vector3D startPosition;
/// <summary>
/// Index into LUMP_DISP_VERTS.
/// </summary>
public int DispVertStart;
/// <summary>
/// Index into LUMP_DISP_TRIS.
/// </summary>
public int DispTriStart;
/// <summary>
/// Power - indicates size of surface (2^power 1)
/// </summary>
public int Power;
/// <summary>
/// Minimum tesselation allowed
/// </summary>
public int MinTess;
/// <summary>
/// Lighting smoothing angle
/// </summary>
public float SmoothingAngle;
/// <summary>
/// Surface contents
/// </summary>
public int Contents;
/// <summary>
/// Which map face this displacement comes from.
/// </summary>
public ushort MapFace;
/// <summary>
/// Index into ddisplightmapalpha.
/// </summary>
public int LightmapAlphaStart;
/// <summary>
/// Index into LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS.
/// </summary>
public int LightmapSamplePositionStart;
/// <summary>
/// Indexed by NEIGHBOREDGE_ defines.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public CDispNeighbor[]? EdgeNeighbors = new CDispNeighbor[4];
/// <summary>
/// Indexed by CORNER_ defines.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public CDispCornerNeighbors[]? CornerNeighbors = new CDispCornerNeighbors[4];
/// <summary>
/// Active verticies
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public uint[]? AllowedVerts = new uint[10];
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class DispInfosLump : Lump
{
/// <summary>
/// Infos
/// </summary>
public DispInfo[]? Infos { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// he DispTris lump (Lump 48) contains "triangle tags" or flags
/// related to the properties of a particular triangle in the
/// displacement mesh.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DispTri
{
/// <summary>
/// Displacement triangle tags.
/// </summary>
public DispTriTag Tags;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class DispTrisLump : Lump
{
/// <summary>
/// Tris
/// </summary>
public DispTri[]? Tris { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The DispVerts lump (Lump 33) contains the vertex data of the displacements.
/// vec is the normalized vector of the offset of each displacement vertex from
/// its original (flat) position; dist is the distance the offset has taken
/// place; and alpha is the alpha-blending of the texture at that vertex.
///
/// A displacement of power p references (2^p + 1)^2 dispverts in the array,
/// starting from the DispVertStart index.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DispVert
{
/// <summary>
/// Vector field defining displacement volume.
/// </summary>
public Vector3D Vec;
/// <summary>
/// Displacement distances.
/// </summary>
public float Dist;
/// <summary>
/// "Per vertex" alpha values.
/// </summary>
public float Alpha;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class DispVertsLump : Lump
{
/// <summary>
/// Verts
/// </summary>
public DispVert[]? Verts { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The edges delimit the face and further refer to the vertices of the
/// face. Each edge is pointing to the start and end vertex of the edge.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Edge
{
/// <summary>
/// Indices into vertex array
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public ushort[]? VertexIndices = new ushort[2];
}
}

View File

@@ -0,0 +1,12 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class EdgesLump : Lump
{
/// <summary>
/// Edge
/// </summary>
public Edge[]? Edges { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class EntitiesLump : Lump
{
/// <summary>
/// Entities
/// </summary>
public Entity[]? Entities { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The entity lump is basically a pure ASCII text section.
/// It consists of the string representations of all entities,
/// which are copied directly from the input file to the output
/// BSP file by the compiler.
///
/// Every entity begins and ends with curly brackets. In between
/// there are the attributes of the entity, one in each line,
/// which are pairs of strings enclosed by quotes. The first
/// string is the name of the attribute (the key), the second one
/// its value. The attribute "classname" is mandatory for every
/// entity specifiying its type and therefore, how it is
/// interpreted by the engine.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class Entity
{
/// <summary>
/// Entity attributes
/// </summary>
public List<KeyValuePair<string, string>>? Attributes { get; set; }
}
}

View File

@@ -0,0 +1,926 @@
using System;
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public enum BspContents : int
{
CONTENTS_EMPTY = -1,
CONTENTS_SOLID = -2,
CONTENTS_WATER = -3,
CONTENTS_SLIME = -4,
CONTENTS_LAVA = -5,
CONTENTS_SKY = -6,
CONTENTS_ORIGIN = -7,
CONTENTS_CLIP = -8,
CONTENTS_CURRENT_0 = -9,
CONTENTS_CURRENT_90 = -10,
CONTENTS_CURRENT_180 = -11,
CONTENTS_CURRENT_270 = -12,
CONTENTS_CURRENT_UP = -13,
CONTENTS_CURRENT_DOWN = -14,
CONTENTS_TRANSLUCENT = -15,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_flags_(Source)"/>
[Flags]
public enum VbspContents : uint
{
/// <summary>
/// No contents
/// </summary>
CONTENTS_EMPTY = 0x00000000,
/// <summary>
/// An eye is never valid in a solid
/// </summary>
CONTENTS_SOLID = 0x00000001,
/// <summary>
/// Translucent, but not watery (glass)
/// </summary>
CONTENTS_WINDOW = 0x00000002,
/// <summary>
/// Unused
/// </summary>
CONTENTS_AUX = 0x00000004,
/// <summary>
/// Alpha-tested "grate" textures. Bullets/sight pass through,
/// but solids don't
/// </summary>
CONTENTS_GRATE = 0x00000008,
/// <summary>
/// Set via %CompileSlime. Unlike Quake II, slime does not do
/// damage; a separate trigger_hurt should be used for this.
/// </summary>
CONTENTS_SLIME = 0x00000010,
/// <summary>
/// Set via %CompileWater.
/// </summary>
CONTENTS_WATER = 0x00000020,
/// <summary>
/// Unknown purpose; only set by %CompilePlayerControlClip.
/// </summary>
CONTENTS_MIST = 0x00000040,
/// <summary>
/// Block AI line of sight
/// </summary>
CONTENTS_BLOCKLOS = 0x00000040,
/// <summary>
/// Things that cannot be seen through (may be non-solid though)
/// </summary>
CONTENTS_OPAQUE = 0x00000080,
/// <summary>
/// Unknown
/// </summary>
CONTENTS_TESTFOGVOLUME = 0x00000100,
/// <summary>
/// Unused
/// </summary>
CONTENTS_UNUSED = 0x00000200,
/// <summary>
/// Unused
/// </summary>
CONTENTS_UNUSED6 = 0x00000400,
/// <summary>
/// If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS
/// if not visible, then grab from the bottom.
/// </summary>
CONTENTS_BLOCKLIGHT = 0x00000400,
/// <summary>
/// Per team contents used to differentiate collisions
/// between players and objects on different teams
/// </summary>
CONTENTS_TEAM1 = 0x00000800,
/// <summary>
/// Per team contents used to differentiate collisions
/// between players and objects on different teams
/// </summary>
CONTENTS_TEAM2 = 0x00001000,
/// <summary>
/// Ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW
/// </summary>
CONTENTS_IGNORE_NODRAW_OPAQUE = 0x00002000,
/// <summary>
/// Hits entities which are MOVETYPE_PUSH (doors, plats, etc.)
/// </summary>
CONTENTS_MOVEABLE = 0x00004000,
/// <summary>
/// Is an areaportal.
/// </summary>
CONTENTS_AREAPORTAL = 0x00008000,
/// <summary>
/// Solid to players, including bots.
/// </summary>
CONTENTS_PLAYERCLIP = 0x00010000,
/// <summary>
/// Solid to monsters, better known in Source as NPCs. Also solid
/// to bots in CSGO, even though they are players.
/// </summary>
CONTENTS_MONSTERCLIP = 0x00020000,
/// <summary>
/// Currents can be added to any other contents, and may be mixed
/// </summary>
CONTENTS_CURRENT_0 = 0x00040000,
/// <summary>
/// Currents can be added to any other contents, and may be mixed
/// </summary>
CONTENTS_CURRENT_90 = 0x00080000,
/// <summary>
/// Currents can be added to any other contents, and may be mixed
/// </summary>
CONTENTS_CURRENT_180 = 0x00100000,
/// <summary>
/// Currents can be added to any other contents, and may be mixed
/// </summary>
CONTENTS_CURRENT_270 = 0x00200000,
/// <summary>
/// Currents can be added to any other contents, and may be mixed
/// </summary>
CONTENTS_CURRENT_UP = 0x00400000,
/// <summary>
/// Currents can be added to any other contents, and may be mixed
/// </summary>
CONTENTS_CURRENT_DOWN = 0x00800000,
/// <summary>
/// Unknown
/// </summary>
CONTENTS_BRUSH_PAINT = 0x00040000,
/// <summary>
/// Unknown
/// </summary>
CONTENTS_GRENADECLIP = 0x00080000,
/// <summary>
/// Unknown
/// </summary>
CONTENTS_DRONECLIP = 0x00100000,
/// <summary>
/// Removed before bsping an entity
/// </summary>
CONTENTS_ORIGIN = 0x01000000,
/// <summary>
/// Should never be on a brush, only in game
/// </summary>
CONTENTS_MONSTER = 0x02000000,
/// <summary>
/// Solid to point traces (ex hitscan weapons) and non-debris
/// physics objects[confirm]. Non-solid to QPhysics entities,
/// such as players.
/// </summary>
CONTENTS_DEBRIS = 0x04000000,
/// <summary>
/// Brushes to be added after vis leafs
/// </summary>
CONTENTS_DETAIL = 0x08000000,
/// <summary>
/// Auto set if any surface has trans
/// </summary>
CONTENTS_TRANSLUCENT = 0x10000000,
/// <summary>
/// Is a ladder
/// </summary>
CONTENTS_LADDER = 0x20000000,
/// <summary>
/// Use accurate hitboxes on trace
/// </summary>
CONTENTS_HITBOX = 0x40000000,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[Flags]
public enum DispTriTag : ushort
{
DISPTRI_TAG_SURFACE = 0x01,
DISPTRI_TAG_WALKABLE = 0x02,
DISPTRI_TAG_BUILDABLE = 0x04,
DISPTRI_FLAG_SURFPROP1 = 0x08,
DISPTRI_FLAG_SURFPROP2 = 0x10,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public enum EmitType
{
/// <summary>
/// 90 degree spotlight
/// </summary>
EMIT_SURFACE,
/// <summary>
/// Simple point light source
/// </summary>
EMIT_POINT,
/// <summary>
/// Spotlight with penumbra
/// </summary>
EMIT_SPOTLIGHT,
/// <summary>
/// Directional light with no falloff
/// (surface must trace to SKY texture)
/// </summary>
EMIT_SKYLIGHT,
/// <summary>
/// Linear falloff, non-lambertian
/// </summary>
EMIT_QUAKELIGHT,
/// <summary>
/// Spherical light source with no falloff
/// (surface must trace to SKY texture)
/// </summary>
EMIT_SKYAMBIENT,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public enum LumpType : int
{
#region BSP and VBSP
/// <summary>
/// The entity lump is basically a pure ASCII text section.
/// It consists of the string representations of all entities,
/// which are copied directly from the input file to the output
/// BSP file by the compiler.
/// </summary>
LUMP_ENTITIES = 0,
/// <summary>
/// This lump is a simple array of binary data structures.
/// Each of this structures defines a plane in 3-dimensional
/// space by using the Hesse normal form
/// </summary>
LUMP_PLANES = 1,
/// <summary>
/// The texture lump is somehow a bit more complex then the
/// other lumps, because it is possible to save textures
/// directly within the BSP file instead of storing them in
/// external WAD files.
/// </summary>
/// <remarks>LUMP_TEXDATA in VBSP</remarks>
LUMP_TEXTURES = 2,
/// <summary>
/// This lump simply consists of all vertices of the BSP tree.
/// They are stored as a primitve array of triples of floats.
/// </summary>
/// <remarks>LUMP_VERTEXES in VBSP</remarks>
LUMP_VERTICES = 3,
/// <summary>
/// The VIS lump contains data, which is irrelevant to the actual
/// BSP tree, but offers a way to boost up the speed of the
/// renderer significantly. Especially complex maps profit from
/// the use if this data. This lump contains the so-called
/// Potentially Visible Sets (PVS) (also called VIS lists) in the
/// same amout of leaves of the tree, the user can enter (often
/// referred to as VisLeaves). The visiblilty lists are stored as
/// sequences of bitfields, which are run-length encoded.
/// </summary>
LUMP_VISIBILITY = 4,
/// <summary>
/// This lump is simple again and contains an array of binary
/// structures, the nodes, which are a major part of the BSP tree.
/// </summary>
LUMP_NODES = 5,
/// <summary>
/// The texinfo lump contains informations about how textures are
/// applied to surfaces. The lump itself is an array of binary data
/// structures.
/// </summary>
LUMP_TEXINFO = 6,
/// <summary>
/// The face lump contains the surfaces of the scene.
/// </summary>
LUMP_FACES = 7,
/// <summary>
/// This is one of the largest lumps in the BSP file. The lightmap
/// lump stores all lightmaps used in the entire map. The lightmaps
/// are arrays of triples of bytes (3 channel color, RGB) and stored
/// continuously.
/// </summary>
LUMP_LIGHTING = 8,
/// <summary>
/// This lump contains the so-called clipnodes, which build a second
/// BSP tree used only for collision detection.
/// </summary>
/// <remarks>LUMP_OCCLUSION in VBSP</remarks>
LUMP_CLIPNODES = 9,
/// <summary>
/// The leaves lump contains the leaves of the BSP tree.
/// </summary>
/// <remarks>LUMP_LEAFS in VBSP</remarks>
LUMP_LEAVES = 10,
/// <summary>
/// The marksurfaces lump is a simple array of short integers.
/// </summary>
/// <remarks>LUMP_FACEIDS in VBSP</remarks>
LUMP_MARKSURFACES = 11,
/// <summary>
/// The edges delimit the face and further refer to the vertices of the
/// face. Each edge is pointing to the start and end vertex of the edge.
/// </summary>
LUMP_EDGES = 12,
/// <summary>
/// This lump represents pretty much the same mechanism as the marksurfaces.
/// A face can insert its surfedge indexes into this array to get the
/// corresponding edges delimitting the face and further pointing to the
/// vertexes, which are required for rendering. The index can be positive
/// or negative. If the value of the surfedge is positive, the first vertex
/// of the edge is used as vertex for rendering the face, otherwise, the
/// value is multiplied by -1 and the second vertex of the indexed edge is
/// used.
/// </summary>
LUMP_SURFEDGES = 13,
/// <summary>
/// A model is kind of a mini BSP tree. Its size is determinded by the
/// bounding box spaned by the first to members of this struct.
/// </summary>
LUMP_MODELS = 14,
#endregion
#region VBSP Only
/// <summary>
/// Internal world lights converted from the entity lump
/// </summary>
LUMP_WORLDLIGHTS = 15,
/// <summary>
/// Index to faces in each leaf
/// </summary>
LUMP_LEAFFACES = 16,
/// <summary>
/// Index to brushes in each leaf
/// </summary>
LUMP_LEAFBRUSHES = 17,
/// <summary>
/// Brush array
/// </summary>
LUMP_BRUSHES = 18,
/// <summary>
/// Brushside array
/// </summary>
LUMP_BRUSHSIDES = 19,
/// <summary>
/// Area array
/// </summary>
LUMP_AREAS = 20,
/// <summary>
/// Portals between areas
/// </summary>
LUMP_AREAPORTALS = 21,
/// <remarks>Source 2004</remarks>
LUMP_PORTALS = 22,
/// <summary>
/// Unused
/// </summary>
/// <remarks>Source 2007/2009</remarks>
LUMP_UNUSED0 = 22,
/// <summary>
/// Static props convex hull lists
/// </summary>
/// <remarks>Source (L4D2 Branch)</remarks>
LUMP_PROPCOLLISION = 22,
/// <summary>
/// Leaves that are enterable by the player
/// </summary>
/// <remarks>Source 2004</remarks>
LUMP_CLUSTERS = 23,
/// <summary>
/// Unused
/// </summary>
/// <remarks>Source 2007/2009</remarks>
LUMP_UNUSED1 = 23,
/// <summary>
/// Static prop convex hulls
/// </summary>
/// <remarks>Source (L4D2 Branch)</remarks>
LUMP_PROPHULLS = 23,
/// <summary>
/// Vertices of portal polygons
/// </summary>
/// <remarks>Source 2004</remarks>
LUMP_PORTALVERTS = 24,
/// <summary>
/// Unused
/// </summary>
/// <remarks>Source 2007/2009</remarks>
LUMP_UNUSED2 = 24,
/// <summary>
/// Used to store client side entities (Similar to Lump #0)
/// </summary>
/// <remarks>Source (TacInt branch)</remarks>
LUMP_FAKEENTITIES = 24,
/// <summary>
/// Static prop collision vertices
/// </summary>
/// <remarks>Source (L4D2 Branch)</remarks>
LUMP_PROPHULLVERTS = 24,
/// <remarks>Source 2004</remarks>
LUMP_CLUSTERPORTALS = 25,
/// <summary>
/// Unused
/// </summary>
/// <remarks>Source 2007/2009</remarks>
LUMP_UNUSED3 = 25,
/// <summary>
/// Static prop per hull triangle index start/count
/// </summary>
/// <remarks>Source (L4D2 Branch)</remarks>
LUMP_PROPTRIS = 25,
/// <summary>
/// Displacement surface array
/// </summary>
LUMP_DISPINFO = 26,
/// <summary>
/// Brush faces array before splitting
/// </summary>
LUMP_ORIGINALFACES = 27,
/// <summary>
/// Displacement physics collision data
/// </summary>
LUMP_PHYSDISP = 28,
/// <summary>
/// Physics collision data
/// </summary>
LUMP_PHYSCOLLIDE = 29,
/// <summary>
/// Face plane normals
/// </summary>
LUMP_VERTNORMALS = 30,
/// <summary>
/// Face plane normal index array
/// </summary>
LUMP_VERTNORMALINDICES = 31,
/// <summary>
/// Displacement lightmap alphas (unused/empty since Source 2006)
/// </summary>
LUMP_DISP_LIGHTMAP_ALPHAS = 32,
/// <summary>
/// Vertices of displacement surface meshes
/// </summary>
LUMP_DISP_VERTS = 33,
/// <summary>
/// Displacement lightmap sample positions
/// </summary>
LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS = 34,
/// <summary>
/// Game-specific data lump
/// </summary>
LUMP_GAME_LUMP = 35,
/// <summary>
/// Data for leaf nodes that are inside water
/// </summary>
LUMP_LEAFWATERDATA = 36,
/// <summary>
/// Water polygon data
/// </summary>
LUMP_PRIMITIVES = 37,
/// <summary>
/// Water polygon vertices
/// </summary>
LUMP_PRIMVERTS = 38,
/// <summary>
/// Water polygon vertex index array
/// </summary>
LUMP_PRIMINDICES = 39,
/// <summary>
/// Embedded uncompressed or LZMA-compressed Zip-format file
/// </summary>
LUMP_PAKFILE = 40,
/// <summary>
/// Clipped portal polygon vertices
/// </summary>
LUMP_CLIPPORTALVERTS = 41,
/// <summary>
/// env_cubemap location array
/// </summary>
LUMP_CUBEMAPS = 42,
/// <summary>
/// Texture name data
/// </summary>
LUMP_TEXDATA_STRING_DATA = 43,
/// <summary>
/// Index array into texdata string data
/// </summary>
LUMP_TEXDATA_STRING_TABLE = 44,
/// <summary>
/// info_overlay data array
/// </summary>
LUMP_OVERLAYS = 45,
/// <summary>
/// Distance from leaves to water
/// </summary>
LUMP_LEAFMINDISTTOWATER = 46,
/// <summary>
/// Macro texture info for faces
/// </summary>
LUMP_FACE_MACRO_TEXTURE_INFO = 47,
/// <summary>
/// Displacement surface triangles
/// </summary>
LUMP_DISP_TRIS = 48,
/// <summary>
/// Compressed win32-specific Havok terrain surface collision data.
/// Deprecated and no longer used.
/// </summary>
/// <remarks>Source 2004</remarks>
LUMP_PHYSCOLLIDESURFACE = 49,
/// <summary>
/// Static prop triangle and string data
/// </summary>
/// <remarks>Source (L4D2 Branch)</remarks>
LUMP_PROP_BLOB = 49,
/// <summary>
/// Tied to any entity that uses the overlay_transition helper in FGD
/// </summary>
LUMP_WATEROVERLAYS = 50,
/// <summary>
/// Alternate lightdata implementation for Xbox
/// </summary>
/// <remarks>Source 2006</remarks>
LUMP_LIGHTMAPPAGES = 51,
/// <summary>
/// Index of LUMP_LEAF_AMBIENT_LIGHTING_HDR
/// </summary>
/// <remarks>Source 2007/2009</remarks>
LUMP_LEAF_AMBIENT_INDEX_HDR = 51,
/// <summary>
/// Alternate lightdata indices for Xbox
/// </summary>
/// <remarks>Source 2006</remarks>
LUMP_LIGHTMAPPAGEINFOS = 52,
/// <summary>
/// Index of LUMP_LEAF_AMBIENT_LIGHTING
/// </summary>
/// <remarks>Source 2007/2009</remarks>
LUMP_LEAF_AMBIENT_INDEX = 52,
/// <summary>
/// HDR lightmap samples
/// </summary>
LUMP_LIGHTING_HDR = 53,
/// <summary>
/// Internal HDR world lights converted from the entity lump
/// </summary>
LUMP_WORLDLIGHTS_HDR = 54,
/// <summary>
/// Per-leaf ambient light samples (HDR)
/// </summary>
LUMP_LEAF_AMBIENT_LIGHTING_HDR = 55,
/// <summary>
/// Per-leaf ambient light samples (LDR)
/// </summary>
LUMP_LEAF_AMBIENT_LIGHTING = 56,
/// <summary>
/// XZip version of pak file for Xbox. Deprecated.
/// </summary>
LUMP_XZIPPAKFILE = 57,
/// <summary>
/// HDR maps may have different face data
/// </summary>
LUMP_FACES_HDR = 58,
/// <summary>
/// Extended level-wide flags. Not present in all levels.
/// </summary>
LUMP_MAP_FLAGS = 59,
/// <summary>
/// Fade distances for overlays
/// </summary>
LUMP_OVERLAY_FADES = 60,
/// <summary>
/// System level settings (min/max CPU & GPU to render this overlay)
/// </summary>
LUMP_OVERLAY_SYSTEM_LEVELS = 61,
/// <summary>
/// PhysX model of the World Brush.
/// </summary>
LUMP_PHYSLEVEL = 62,
/// <summary>
/// Displacement multiblend info
/// </summary>
LUMP_DISP_MULTIBLEND = 63,
#endregion
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public enum PlaneType : int
{
// Plane is perpendicular to given axis
PLANE_X = 0,
PLANE_Y = 1,
PLANE_Z = 2,
// Non-axial plane is snapped to the nearest
PLANE_ANYX = 3,
PLANE_ANYY = 4,
PLANE_ANYZ = 5,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)/Static_prop_flags"/>
[Flags]
public enum StaticPropFlags : uint
{
/// <summary>
/// Set by engine at runtime if the model fades out at a distance.
/// </summary>
STATIC_PROP_FLAG_FADES = 0x01,
/// <summary>
/// Set by engine at runtime if the model's lighting origin is
/// different from its position in the world.
/// </summary>
STATIC_PROP_USE_LIGHTING_ORIGIN = 0x02,
/// <summary>
/// Computed at run time based on dx level
/// </summary>
STATIC_PROP_NO_DRAW = 0x04,
/// <summary>
/// Set if disableflashlight is enabled.
/// </summary>
STATIC_PROP_NO_FLASHLIGHT = 0x04,
/// <summary>
/// Set if ignorenormals is enabled.
/// </summary>
STATIC_PROP_IGNORE_NORMALS = 0x08,
/// <summary>
/// Set if disableshadows is enabled.
/// </summary>
STATIC_PROP_NO_SHADOW = 0x10,
/// <summary>
/// Set if disableshadows is enabled.
/// </summary>
STATIC_PROP_SCREEN_SPACE_FADE = 0x20,
/// <summary>
/// Set if drawinfastreflection is enabled.
/// </summary>
STATIC_PROP_MARKED_FOR_FAST_REFLECTION = 0x20,
/// <summary>
/// In vrad, compute lighting at lighting origin,
/// not for each vertex
/// </summary>
STATIC_PROP_NO_PER_VERTEX_LIGHTING = 0x40,
/// <summary>
/// Disable self shadowing in vrad
/// </summary>
STATIC_PROP_NO_SELF_SHADOWING = 0x80,
/// <summary>
/// Whether we should do per-texel lightmaps in vrad
/// </summary>
STATIC_PROP_NO_PER_TEXEL_LIGHTING = 0x100,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)/Static_prop_flags"/>
[Flags]
public enum StaticPropFlagsEx : uint
{
/// <summary>
/// Set if disableshadowdepth is enabled.
/// </summary>
STATIC_PROP_FLAGS_EX_DISABLE_SHADOW_DEPTH = 0x00000001,
/// <summary>
/// Automatically set at runtime
/// </summary>
STATIC_PROP_FLAGS_EX_DISABLE_CSM = 0x00000002,
/// <summary>
/// Set if enablelightbounce is enabled.
/// </summary>
STATIC_PROP_FLAGS_EX_ENABLE_LIGHT_BOUNCE = 0x00000004,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_flags_(Source)"/>
[Flags]
public enum SurfaceFlag : uint
{
/// <summary>
/// Normally set on any surface that matches a RAD file entry;
/// not actually written to the BSP, unlike Quake II.
/// </summary>
SURF_LIGHT = 0x0001,
/// <summary>
/// Deprecated: Legacy Quake II flag; deprecated in favor of
/// surface properties.
/// </summary>
SURF_SLICK = 0x0002,
/// <summary>
/// Shows only the 2D skybox. Set via $Compile2DSky
/// </summary>
SURF_SKY2D = 0x0002,
/// <summary>
/// Shows both the 2D and 3D skybox. Set via $CompileSky
/// </summary>
SURF_SKY = 0x0004,
/// <summary>
/// Tells VVIS and the engine renderer that the surface is water.
/// Set via %CompileWater, but not %CompileSlime.
/// </summary>
SURF_WARP = 0x0008,
/// <summary>
/// Surface is translucent, either via $translucent or $alpha.
/// </summary>
SURF_TRANS = 0x0010,
/// <summary>
/// Deprecated: Legacy Quake II flag; deprecated in favor of
/// surface properties.
/// </summary>
SURF_WET = 0x0020,
/// <summary>
/// Set via %NoPortal
/// </summary>
SURF_NOPORTAL = 0x0020,
/// <summary>
/// Deprecated: Legacy Quake II flag; deprecated in favor of
/// material proxies.
/// </summary>
SURF_FLOWING = 0x0040,
/// <summary>
/// Set via %CompileTrigger. Doesn't do anything in the PC versions.
/// </summary>
SURF_TRIGGER = 0x0040,
/// <summary>
/// Set via %CompileNoDraw
/// </summary>
SURF_NODRAW = 0x0080,
/// <summary>
/// Set via %CompileHint
/// </summary>
SURF_HINT = 0x0100,
/// <summary>
/// Set via %CompileSkip. Should never be used on anything except
/// a hint brush.
/// </summary>
SURF_SKIP = 0x0200,
/// <summary>
/// Don't calculate light
/// </summary>
SURF_NOLIGHT = 0x0400,
/// <summary>
/// Calculate three lightmaps for the surface for bumpmapping
/// </summary>
SURF_BUMPLIGHT = 0x0800,
/// <summary>
/// Don't receive shadows
/// </summary>
SURF_NOSHADOWS = 0x1000,
/// <summary>
/// Don't receive decals
/// </summary>
SURF_NODECALS = 0x2000,
/// <summary>
/// Don't subdivide patches on this surface
/// </summary>
SURF_NOCHOP = 0x4000,
/// <summary>
/// Surface is part of a hitbox
/// </summary>
SURF_HITBOX = 0x8000,
}
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[Flags]
public enum TextureFlag : uint
{
/// <summary>
/// Disable lightmaps and subdivision for the surface
/// </summary>
/// <remarks>Used by sky and liquids</remarks>
DisableLightmaps = 0x01,
}
}

View File

@@ -1,29 +0,0 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// Half-Life Level
/// </summary>
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
public sealed class File
{
/// <summary>
/// Header data
/// </summary>
public Header? Header { get; set; }
/// <summary>
/// Lumps
/// </summary>
public Lump?[]? Lumps { get; set; }
/// <summary>
/// Texture header data
/// </summary>
public TextureHeader? TextureHeader { get; set; }
/// <summary>
/// Textures
/// </summary>
public Texture?[]? Textures { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The Game lump (Lump 35) seems to be intended to be used for
/// map data that is specific to a particular game using the Source
/// engine, so that the file format can be extended without altering
/// the previously defined format.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class GameLump
{
/// <summary>
/// Number of game lumps
/// </summary>
public int LumpCount;
/// <summary>
/// <see cref="LumpCount"/>
/// </summary>
public GameLumpDirectory[]? Directories;
}
}

View File

@@ -0,0 +1,40 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The Game lump (Lump 35) seems to be intended to be used for
/// map data that is specific to a particular game using the Source
/// engine, so that the file format can be extended without altering
/// the previously defined format.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class GameLumpDirectory
{
/// <summary>
/// Gamelump ID
/// </summary>
public int Id;
/// <summary>
/// Flags
/// </summary>
public ushort Flags;
/// <summary>
/// Gamelump version
/// </summary>
public ushort Version;
/// <summary>
/// Offset to this gamelump
/// </summary>
public int FileOffset;
/// <summary>
/// Length
/// </summary>
public int FileLength;
}
}

View File

@@ -1,14 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Header
{
/// <summary>
/// Version
/// </summary>
public uint Version;
}
}

View File

@@ -0,0 +1,17 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// To associate each leaf with its collection of ambient samples,
/// the ambient lighting index lumps (Lumps 51 and 52) are used.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class LeafAmbientIndex
{
public ushort AmbientSampleCount;
public ushort FirstAmbientSample;
}
}

View File

@@ -0,0 +1,41 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The ambient lighting lumps (Lumps 55 and 56) are present in
/// BSP version 20 and later. Lump 55 is used for HDR lighting,
/// and Lump 56 is used for LDR lighting. These lumps are used to
/// store the volumetric ambient lighting information in each leaf
/// (i.e. lighting information for entities such as NPCs, the
/// viewmodel, and non-static props). Prior to version 20, this
/// data was stored in the leaf lump (Lump 10), in the dleaf_t
/// structure, with far less precision than this newer lump allows.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class LeafAmbientLighting
{
public CompressedLightCube Cube;
/// <summary>
/// Fixed point fraction of leaf bounds
/// </summary>
public byte X;
/// <summary>
/// Fixed point fraction of leaf bounds
/// </summary>
public byte Y;
/// <summary>
/// Fixed point fraction of leaf bounds
/// </summary>
public byte Z;
/// <summary>
/// Unused
/// </summary>
public byte Pad;
}
}

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The leafbrush lump (Lump 17) is an array of unsigned shorts which are
/// used to map from brushes referenced in the leaf structure to indices in
/// the brush array.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class LeafBrushesLump : Lump
{
/// <summary>
/// Map
/// </summary>
public ushort[]? Map { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The leafface lump (Lump 16) is an array of unsigned shorts which are
/// used to map from faces referenced in the leaf structure to indices in
/// the face array.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class LeafFacesLump : Lump
{
/// <summary>
/// Map
/// </summary>
public ushort[]? Map { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// This is one of the largest lumps in the BSP file. The lightmap
/// lump stores all lightmaps used in the entire map. The lightmaps
/// are arrays of triples of bytes (3 channel color, RGB) and stored
/// continuously.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class LightmapLump : Lump
{
/// <summary>
/// Lightmap RGB values
/// </summary>
/// <remarks>Array of 3-byte values</remarks>
public byte[,]? Lightmap { get; set; }
}
}

View File

@@ -1,19 +1,12 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Lump
/// <summary>
/// Represents a common Lump type
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public abstract class Lump
{
/// <summary>
/// Offset
/// </summary>
public uint Offset;
/// <summary>
/// Length
/// </summary>
public uint Length;
// No shared fields between types
}
}

View File

@@ -0,0 +1,40 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// BSP files for console platforms such as PlayStation 3 and
/// Xbox 360 usually have their lumps compressed with LZMA.
/// In this case, the lump data starts with the following header
/// (from public/tier1/lzmaDecoder.h), which is used in place of
/// the standard 13-byte LZMA header.
///
/// lzmaSize denotes the size (in bytes) of compressed data, it
/// is equal to the size of a lump minus 17 bytes (lzma header).
/// actualSize denotes the size of decompressed data. properties[5]
/// field are used solely for LZMA decoding.
///
/// There are two special cases for compression: LUMP_PAKFILE is never
/// compressed as a lump (the contents of the zip are compressed instead)
/// and each of the game lumps in LUMP_GAME_LUMP are compressed individually.
/// The compressed size of a game lump can be determined by subtracting
/// the current game lump's offset with that of the next entry. For this
/// reason, when game lumps are compressed the last game lump is always
/// an empty dummy which only contains the offset.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class LzmaHeader
{
public uint Id;
/// <remarks>Little-endian</remarks>
public uint ActualSize;
/// <remarks>Little-endian</remarks>
public uint LzmaSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[]? Properties = new byte[5];
}
}

View File

@@ -0,0 +1,19 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The marksurfaces lump is a simple array of short integers.
///
/// This lump is a simple table for redirecting the marksurfaces
/// indexes in the leafs to the actial face indexes. A leaf inserts
/// it's marksurface indexes into this array and gets the associated
/// faces contained within this leaf.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class MarksurfacesLump : Lump
{
/// <summary>
/// Marksurfaces
/// </summary>
public ushort[]? Marksurfaces { get; set; }
}
}

View File

@@ -0,0 +1,44 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// Each of this structs describes a texture. The name of the
/// texture is a string and may be 16 characters long (including
/// the null-character at the end, char equals a 8bit signed
/// integer). The name of the texture is needed, if the texture
/// has to be found and loaded from an external WAD file.
/// Furthermore, the struct contains the width and height of
/// the texture. The 4 offsets at the end can either be zero,
/// if the texture is stored in an external WAD file, or point
/// to the beginnings of the binary texture data within the
/// texture lump relative to the beginning of it's BSPMIPTEX struct.
/// </summary>
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MipTexture
{
/// <summary>
/// Name of texture
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAXTEXTURENAME)]
public string? Name;
/// <summary>
/// Extends of the texture
/// </summary>
public uint Width;
/// <summary>
/// Extends of the texture
/// </summary>
public uint Height;
/// <summary>
/// Offsets to texture mipmaps BSPMIPTEX
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.MIPLEVELS)]
public uint[]? Offsets;
}
}

View File

@@ -0,0 +1,40 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The doccluderdata_t structure contains flags and dimensions
/// of the occluder, as well as the area where it remains.
/// firstpoly is the first index into the doccluderpolydata_t
/// with a total of polycount entries.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class OccluderData
{
public int Flags;
/// <summary>
/// Index into doccluderpolys
/// </summary>
public int FirstPoly;
/// <summary>
/// Amount of polygons
/// </summary>
public int PolyCount;
/// <summary>
/// Minima of all vertices
/// </summary>
public Vector3D Mins;
/// <summary>
/// Maxima of all vertices
/// </summary>
public Vector3D Maxs;
/// <remarks>Since v1</remarks>
public int Area;
}
}

View File

@@ -0,0 +1,29 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// Occluder polygons are stored in the doccluderpolydata_t
/// structure and contain the firstvertexindex field, which
/// is the first index into the vertex array of the occluder,
/// which are again indices for the vertex array of the vertex
/// lump (Lump 3). The total number of vertex indices is
/// stored in vertexcount.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class OccluderPolyData
{
/// <summary>
/// Index into doccludervertindices
/// </summary>
public int FirstVertexIndex;
/// <summary>
/// Amount of vertex indices
/// </summary>
public int VertexCount;
public int PlanEnum;
}
}

View File

@@ -0,0 +1,46 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The occlusion lump (Lump 9) contains the polygon geometry and some
/// flags used by func_occluder entities. Unlike other brush entities,
/// func_occluders don't use the 'model' key in the entity lump.
/// Instead, the brushes are split from the entities during the compile
/// process and numeric occluder keys are assigned as 'occludernum'.
/// Brush sides textured with tools/toolsoccluder or tools/toolstrigger
/// are then stored together with the occluder keys and some additional
/// info in this lump.
///
/// The lump is divided into three parts and begins with a integer value
/// with the total number of occluders, followed by an array of
/// doccluderdata_t fields of the same size. The next part begins with
/// another integer value, this time for the total number of occluder
/// polygons, as well as an array of doccluderpolydata_t fields of equal
/// size. Part three begins with another integer value for the amount of
/// occluder polygon vertices, followed by an array of integer values for
/// the vertex indices, again of the same size.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class OcclusionLump : Lump
{
public int Count;
/// <summary>
/// <see cref="Count">
/// </summary>
public OccluderData[]? Data;
public int PolyDataCount;
/// <summary>
/// <see cref="PolyDataCount">
/// </summary>
public OccluderPolyData[]? PolyData;
public int VertexIndexCount;
/// <summary>
/// <see cref="VertexIndexCount">
/// </summary>
public int[]? VertexIndices;
}
}

View File

@@ -0,0 +1,48 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// Unlike the simpler decals (infodecal entities), info_overlays
/// are removed from the entity lump and stored separately in the
/// Overlay lump (Lump 45).
///
/// The FaceCountAndRenderOrder member is split into two parts;
/// the lower 14 bits are the number of faces that the overlay
/// appears on, with the top 2 bits being the render order of
/// the overlay (for overlapping decals). The Ofaces array, which
/// is 64 elements in size (OVERLAY_BSP_FACE_COUNT) are the indices
/// into the face array indicating which map faces the overlay
/// should be displayed on. The other elements set the texture,
/// scale, and orientation of the overlay decal. There is no
/// enforced limit on overlays inside the engine. VBSP enforces
/// a limit of 512 (MAX_MAP_OVERLAYS, 1024 in Counter-Strike:
/// Global Offensive), but custom compilers can circumvent this.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Overlay
{
public int Id;
public short TexInfo;
public ushort FaceCountAndRenderOrder;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.OVERLAY_BSP_FACE_COUNT)]
public int[]? Ofaces = new int[Constants.OVERLAY_BSP_FACE_COUNT];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public float[]? U = new float[2];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public float[]? V = new float[2];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public Vector3D[]? UVPoints = new Vector3D[4];
public Vector3D Origin;
public Vector3D BasisNormal;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class OverlaysLump : Lump
{
/// <summary>
/// Overlays
/// </summary>
public Overlay[]? Overlays { get; set; }
}
}

View File

@@ -0,0 +1,40 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// Each of this structures defines a plane in 3-dimensional
/// space by using the Hesse normal form: normal * point - distance = 0
///
/// Where vNormal is the normalized normal vector of the plane
/// and fDist is the distance of the plane to the origin of
/// the coord system. Additionally, the structure also saves an
/// integer describing the orientation of the plane in space.
/// If nType equals PLANE_X, then the normal of the plane will
/// be parallel to the x axis, meaning the plane is perpendicular
/// to the x axis. If nType equals PLANE_ANYX, then the plane's
/// normal is nearer to the x axis then to any other axis.
/// This information is used by the renderer to speed up some
/// computations.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Plane
{
/// <summary>
/// The planes normal vector
/// </summary>
public Vector3D NormalVector;
/// <summary>
/// Plane equation is: vNormal * X = fDist
/// </summary>
public float Distance;
/// <summary>
/// Plane type
/// </summary>
public PlaneType PlaneType;
}
}

View File

@@ -0,0 +1,12 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class PlanesLump : Lump
{
/// <summary>
/// Planes
/// </summary>
public Plane[]? Planes { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// QAngle is a C++ class in Source that represents a three-dimensional
/// extrinsic Tait-Bryan rotations following the right-hand rule, offset
/// from the cardinal Z axis.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct QAngle
{
public float X { get; set; }
public float Y { get; set; }
public float Z { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// Of interest is the gamelump which is used to store prop_static entities,
/// which uses the gamelump ID of 'sprp' ASCII (1936749168 decimal). Unlike
/// most other entities, static props are not stored in the entity lump. The
/// gamelump formats used in Source are defined in the public/gamebspfile.h
/// header file.
///
/// The first element of the static prop game lump is the dictionary; this is
/// an integer count followed by the list of model (prop) names used in the map
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class StaticPropDictLump
{
public int DictEntries;
/// <summary>
/// Model name
/// </summary>
/// <remarks>[dictEntries][128]</remarks>
public char[,]? Name;
}
}

View File

@@ -0,0 +1,18 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// Presumably, this array is used to index into the leaf lump
/// to locate the leaves that each prop static is located in.
/// Note that a prop static may span several leaves.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class StaticPropLeafLump
{
public int LeafEntries;
/// <summary>
/// <see cref="LeafEntries">
/// </summary>
public ushort[]? Leaf;
}
}

View File

@@ -0,0 +1,185 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The coordinates of the prop are given by the Origin member; its
/// orientation (pitch, yaw, roll) is given by the Angles entry, which
/// is a 3-float vector. The PropType element is an index into the
/// dictionary of prop model names, given above. The other elements
/// correspond to the location of the prop in the BSP structure of the
/// map, its lighting, and other entity properties as set in Hammer.
/// The other elements (ForcedFadeScale, etc.) are only present in the
/// static prop structure if the gamelump's specified version is high enough
/// (see dgamelump_t.version); both version 4 and version 5 static prop
/// gamelumps are used in official Half-Life 2 maps. Version 6 has been
/// encountered in Team Fortress 2; Version 7 is used in some Left 4 Dead
/// maps, and a modified version 7 is present in Zeno Clash maps. Version 8
/// is used predominantly in Left 4 Dead, and version 9 in Left 4 Dead 2.
/// The new version 10 appears in Tactical Intervention. Version 11 is used in
/// Counter-Strike: Global Offensive since the addition of uniform prop scaling
/// (before this it was version 10). After version 7, DX level options were
/// removed. In version 11 XBox 360 flags were removed.
///
/// Version 7* is used by games built on Source 2013 Multiplayer
/// ( Team Fortress 2, Counter-Strike: Source, etc.) and may come across as
/// either version 7 or 10. Specifically, Team Fortress 2 has referred to it
/// as version 7 in the past but now refers to it as version 10 even though
/// they are identical. This version's structure is based on version 6 but
/// rearranged such that Flags is an int and at the bottom, above two new
/// entries. These new entries (LightmapResX and LightmapResY) control the
/// width and height of the prop's lightmap image and are specific to this
/// version.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class StaticPropLump
{
#region v4
/// <summary>
/// Origin
/// </summary>
public Vector3D Origin;
/// <summary>
/// Orientation (pitch yaw roll)
/// </summary>
public QAngle Angles;
#endregion
#region v4
/// <summary>
/// Index into model name dictionary
/// </summary>
public ushort PropType;
/// <summary>
/// Index into leaf array
/// </summary>
public ushort FirstLeaf;
public ushort LeafCount;
/// <summary>
/// Solidity type
/// </summary>
public byte Solid;
#endregion
#region Every version except v7*
[MarshalAs(UnmanagedType.U1)]
public StaticPropFlags FlagsV4;
#endregion
#region v4 still
/// <summary>
/// Model skin numbers
/// </summary>
public int Skin;
public float FadeMinDist;
public float FadeMaxDist;
/// <summary>
/// For lighting
/// </summary>
public Vector3D LightingOrigin;
#endregion
#region Since v5
/// <summary>
/// Fade distance scale
/// </summary>
public float ForcedFadeScale;
#endregion
#region v6, v7, and v7* only
/// <summary>
/// Minimum DirectX version to be visible
/// </summary>
public ushort MinDXLevel;
/// <summary>
/// Maximum DirectX version to be visible
/// </summary>
public ushort MaxDXLevel;
#endregion
#region v7* only
[MarshalAs(UnmanagedType.U4)]
public byte FlagsV7;
/// <summary>
/// Lightmap image width
/// </summary>
public ushort LightmapResX;
/// <summary>
/// Lightmap image height
/// </summary>
public ushort LightmapResY;
#endregion
#region Since v8
public byte MinCPULevel;
public byte MaxCPULevel;
public byte MinGPULevel;
public byte MaxGPULevel;
#endregion
#region Since v7
/// <summary>
/// Per instance color and alpha modulation
/// </summary>
public ColorRGBExp32 DiffuseModulation;
#endregion
#region v9 and v10 only
/// <summary>
/// If true, don't show on XBox 360 (4-bytes long)
/// </summary>
public bool DisableX360;
#endregion
#region Since v10
/// <summary>
/// Further bitflags.
/// </summary>
public StaticPropFlagsEx FlagsEx;
#endregion
#region Since v11
/// <summary>
/// Prop scale
/// </summary>
public float UniformScale;
#endregion
}
}

View File

@@ -0,0 +1,22 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// This lump represents pretty much the same mechanism as the marksurfaces.
/// A face can insert its surfedge indexes into this array to get the
/// corresponding edges delimitting the face and further pointing to the
/// vertexes, which are required for rendering. The index can be positive
/// or negative. If the value of the surfedge is positive, the first vertex
/// of the edge is used as vertex for rendering the face, otherwise, the
/// value is multiplied by -1 and the second vertex of the indexed edge is
/// used.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class SurfedgesLump : Lump
{
/// <summary>
/// Surfedges
/// </summary>
public int[]? Surfedges { get; set; }
}
}

View File

@@ -0,0 +1,40 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The reflectivity vector corresponds to the RGB components of the reflectivity
/// of the texture, as derived from the material's .vtf file. This is probably
/// used in radiosity (lighting) calculations of what light bounces from the
/// texture's surface. The nameStringTableID is an index into the TexdataStringTable
/// array (below). The other members relate to the texture's source image.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Texdata
{
/// <summary>
/// RGB reflectivity
/// </summary>
public Vector3D Reflectivity;
/// <summary>
/// Index into TexdataStringTable
/// </summary>
public int NameStringTableID;
/// <summary>
/// Source image
/// </summary>
public int Width;
/// <summary>
/// Source image
/// </summary>
public int Height;
public int ViewWidth;
public int ViewHeight;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class TexdataLump : Lump
{
/// <summary>
/// Texdatas
/// </summary>
public Texdata[]? Texdatas { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The TexdataStringData lump consists of concatenated null-terminated
/// strings giving the texture name.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class TexdataStringData : Lump
{
/// <summary>
/// Strings
/// </summary>
public string[]? Strings { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The TexdataStringTable (Lump 44) is an array of integers which
/// are offsets into the TexdataStringData (lump 43).
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class TexdataStringTable : Lump
{
/// <summary>
/// Offsets
/// </summary>
public int[]? Offsets { get; set; }
}
}

View File

@@ -1,41 +0,0 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
public sealed class Texture
{
/// <summary>
/// Name
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Width
/// </summary>
public uint Width { get; set; }
/// <summary>
/// Height
/// </summary>
public uint Height { get; set; }
/// <summary>
/// Offsets
/// </summary>
public uint[]? Offsets { get; set; }
/// <summary>
/// Texture data
/// </summary>
public byte[]? TextureData { get; set; }
/// <summary>
/// Palette size
/// </summary>
public uint PaletteSize { get; set; }
/// <summary>
/// Palette data
/// </summary>
public byte[]? PaletteData { get; set; }
}
}

View File

@@ -1,17 +1,18 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/BSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class TextureHeader
{
/// <summary>
/// Texture count
/// Number of BSPMIPTEX structures
/// </summary>
public uint TextureCount { get; set; }
public uint MipTextureCount { get; set; }
/// <summary>
/// Offsets
/// </summary>
/// <remarks>TextureCount entries</remarks>
public uint[]? Offsets { get; set; }
/// <remarks><see cref="MipTextureCount"> entries</remarks>
public int[]? Offsets { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class TextureLump : Lump
{
/// <summary>
/// Texture header data
/// </summary>
public TextureHeader? Header { get; set; }
/// <summary>
/// Textures
/// </summary>
public MipTexture[]? Textures { get; set; }
}
}

View File

@@ -0,0 +1,105 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The face lump (Lump 7) contains the major geometry of the map,
/// used by the game engine to render the viewpoint of the player.
/// The face lump contains faces after they have undergone the BSP
/// splitting process; they therefore do not directly correspond to
/// the faces of brushes created in Hammer. Faces are always flat,
/// convex polygons, though they can contain edges that are co-linear.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class VbspFace
{
/// <summary>
/// The plane number
/// </summary>
public ushort PlaneNum;
/// <summary>
/// Faces opposite to the node's plane direction
/// </summary>
public byte Side;
/// <summary>
/// of on node, 0 if in leaf
/// </summary>
public byte OnNode;
/// <summary>
/// Index of the first surfedge
/// </summary>
public int FirstEdgeIndex;
/// <summary>
/// Number of consecutive surfedges
/// </summary>
public short NumberOfEdges;
/// <summary>
/// Index of the texture info structure
/// </summary>
public short TextureInfoIndex;
/// <summary>
/// Index of the displacement info structure
/// </summary>
public short DisplacementInfoIndex;
/// <summary>
/// ?
/// </summary>
public short SurfaceFogVolumeID;
/// <summary>
/// Switchable lighting info
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[]? Styles = new byte[4];
/// <summary>
/// Offset into lightmap lump
/// </summary>
public int LightmapOffset;
/// <summary>
/// Face area in units^2
/// </summary>
public float Area;
/// <summary>
/// Texture lighting info
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public int[]? LightmapTextureMinsInLuxels = new int[2];
/// <summary>
/// Texture lighting info
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public int[]? LightmapTextureSizeInLuxels = new int[2];
/// <summary>
/// Original face this was split from
/// </summary>
public int OrigFace;
/// <summary>
/// Primitives
/// </summary>
public ushort PrimitiveCount;
/// <summary>
/// First primitive ID
/// </summary>
public ushort FirstPrimitiveID;
/// <summary>
/// Lightmap smoothing group
/// </summary>
public uint SmoothingGroups;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VbspFacesLump : Lump
{
/// <summary>
/// Faces
/// </summary>
public VbspFace[]? Faces { get; set; }
}
}

View File

@@ -0,0 +1,363 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// Half-Life Level
/// </summary>
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/VBSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VbspFile
{
/// <summary>
/// Header data
/// </summary>
public VbspHeader? Header { get; set; }
#region Lumps
/// <summary>
/// LUMP_ENTITIES [0]
/// </summary>
public EntitiesLump? Entities { get; set; }
/// <summary>
/// LUMP_PLANES [1]
/// </summary>
public PlanesLump? PlanesLump { get; set; }
/// <summary>
/// LUMP_TEXDATA [2]
/// </summary>
public TexdataLump? TexdataLump { get; set; }
/// <summary>
/// LUMP_VERTEXES [3]
/// </summary>
public VerticesLump? VerticesLump { get; set; }
/// <summary>
/// LUMP_VISIBILITY [4]
/// </summary>
public VisibilityLump? VisibilityLump { get; set; }
/// <summary>
/// LUMP_NODES [5]
/// </summary>
public VbspNodesLump? NodesLump { get; set; }
/// <summary>
/// LUMP_TEXINFO [6]
/// </summary>
public VbspTexinfoLump? TexinfoLump { get; set; }
/// <summary>
/// LUMP_FACES [7]
/// </summary>
public VbspFacesLump? FacesLump { get; set; }
/// <summary>
/// LUMP_LIGHTING [8]
/// </summary>
public LightmapLump? LightmapLump { get; set; }
/// <summary>
/// LUMP_OCCLUSION [9]
/// </summary>s
public OcclusionLump? OcclusionLump { get; set; }
/// <summary>
/// LUMP_LEAVES [10]
/// </summary>
public VbspLeavesLump? LeavesLump { get; set; }
/// <summary>
/// LUMP_FACEIDS [11]
/// </summary>
public MarksurfacesLump? MarksurfacesLump { get; set; }
/// <summary>
/// LUMP_EDGES [12]
/// </summary>
public EdgesLump? EdgesLump { get; set; }
/// <summary>
/// LUMP_SURFEDGES [13]
/// </summary>
public SurfedgesLump? SurfedgesLump { get; set; }
/// <summary>
/// LUMP_MODELS [14]
/// </summary>
public VbspModelsLump? ModelsLump { get; set; }
/// <summary>
/// LUMP_WORLDLIGHTS [15]
/// </summary>
public WorldLightsLump? LDRWorldLightsLump { get; set; }
/// <summary>
/// LUMP_LEAFFACES [16]
/// </summary>
public LeafFacesLump? LeafFacesLump { get; set; }
/// <summary>
/// LUMP_LEAFBRUSHES [17]
/// </summary>
public LeafBrushesLump? LeafBrushesLump { get; set; }
/// <summary>
/// LUMP_BRUSHES [18]
/// </summary>
public BrushesLump? BrushesLump { get; set; }
/// <summary>
/// LUMP_BRUSHSIDES [19]
/// </summary>
public BrushsidesLump? BrushsidesLump { get; set; }
/// <summary>
/// LUMP_AREAS [20]
/// </summary>
/// TODO: Find definition and implement
// public AreasLump? AreasLump { get; set; }
/// <summary>
/// LUMP_AREAPORTALS [21]
/// </summary>
/// TODO: Find definition and implement
// public AreaPortalsLump? AreaPortalsLump { get; set; }
/// <summary>
/// LUMP_PORTALS / LUMP_UNUSED0 / LUMP_PROPCOLLISION [22]
/// </summary>
/// TODO: Find definition and implement
// public PortalsLump? PortalsLump { get; set; }
/// <summary>
/// LUMP_CLUSTERS / LUMP_UNUSED1 / LUMP_PROPHULLS [23]
/// </summary>
/// TODO: Find definition and implement
// public ClustersLump? ClustersLump { get; set; }
/// <summary>
/// LUMP_PORTALVERTS / LUMP_UNUSED2 / LUMP_FAKEENTITIES / LUMP_PROPHULLVERTS [24]
/// </summary>
/// TODO: Find definition and implement
// public PortalVertsLump? PortalVertsLump { get; set; }
/// <summary>
/// LUMP_CLUSTERPORTALS / LUMP_UNUSED3 / LUMP_PROPTRIS [25]
/// </summary>
/// TODO: Find definition and implement
// public ClusterPortalsLump? ClusterPortalsLump { get; set; }
/// <summary>
/// LUMP_DISPINFO [26]
/// </summary>
public DispInfosLump? DispInfoLump { get; set; }
/// <summary>
/// LUMP_ORIGINALFACES [27]
/// </summary>
public VbspFacesLump? OriginalFacesLump { get; set; }
/// <summary>
/// LUMP_PHYSDISP [28]
/// </summary>
/// TODO: Find definition and implement
// public PhysDispLump? PhysDispLump { get; set; }
// TODO: Implement Lump 29
// https://developer.valvesoftware.com/wiki/BSP_(Source)#Physics
/// <summary>
/// LUMP_VERTNORMALS [30]
/// </summary>
/// TODO: Find definition and implement
// public VertNormalsLump? VertNormalsLump { get; set; }
/// <summary>
/// LUMP_VERTNORMALINDICES [31]
/// </summary>
/// TODO: Find definition and implement
// public VertNormalIndicesLump? VertNormalIndicesLump { get; set; }
/// <summary>
/// LUMP_DISP_LIGHTMAP_ALPHAS [32]
/// </summary>
/// TODO: Find definition and implement
// public DispLightmapAlphasLump? DispLightmapAlphasLump { get; set; }
/// <summary>
/// LUMP_DISP_VERTS [33]
/// </summary>
public DispVertsLump? DispVertLump { get; set; }
/// <summary>
/// LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS [34]
/// </summary>
/// TODO: Find definition and implement
// public DispLightmapSamplePositions? DispLightmapSamplePositions { get; set; }
/// <summary>
/// LUMP_GAME_LUMP [35]
/// </summary>
public GameLump? GameLump { get; set; }
/// <summary>
/// LUMP_LEAFWATERDATA [36]
/// </summary>
/// TODO: Find definition and implement
// public LeafWaterDataLump? LeafWaterDataLump { get; set; }
/// <summary>
/// LUMP_PRIMITIVES [37]
/// </summary>
/// TODO: Find definition and implement
// public PrimitivesLump? PrimitivesLump { get; set; }
/// <summary>
/// LUMP_PRIMVERTS [38]
/// </summary>
/// TODO: Find definition and implement
// public PrimVertsLump? PrimVertsLump { get; set; }
/// <summary>
/// LUMP_PRIMINDICES [39]
/// </summary>
/// TODO: Find definition and implement
// public PrimIndicesLump? PrimIndicesLump { get; set; }
// TODO: Implement Lump 40
// https://developer.valvesoftware.com/wiki/BSP_(Source)#Pakfile
/// <summary>
/// LUMP_CLIPPORTALVERTS [41]
/// </summary>
/// TODO: Find definition and implement
// public ClipPortalVertsLump? ClipPortalVertsLump { get; set; }
/// <summary>
/// LUMP_CUBEMAPS [42]
/// </summary>
public CubemapsLump? CubemapLump { get; set; }
/// <summary>
/// LUMP_TEXDATA_STRING_DATA [43]
/// </summary>
public TexdataStringData? TexdataStringData { get; set; }
/// <summary>
/// LUMP_TEXDATA_STRING_TABLE [44]
/// </summary>
public TexdataStringTable? TexdataStringTable { get; set; }
/// <summary>
/// LUMP_OVERLAYS [45]
/// </summary>
public OverlaysLump? OverlaysLump { get; set; }
/// <summary>
/// LUMP_LEAFMINDISTTOWATER [46]
/// </summary>
/// TODO: Find definition and implement
// public LeafMindIsToWaterLump? LeafMindIsToWaterLump { get; set; }
/// <summary>
/// LUMP_FACE_MACRO_TEXTURE_INFO [47]
/// </summary>
/// TODO: Find definition and implement
// public FaceMacroTextureInfoLump? FaceMacroTextureInfoLump { get; set; }
/// <summary>
/// LUMP_DISP_TRIS [48]
/// </summary>
public DispTrisLump? DispTrisLump { get; set; }
/// <summary>
/// LUMP_PHYSCOLLIDESURFACE / LUMP_PROP_BLOB [49]
/// </summary>
/// TODO: Find definition and implement
// public PhysCollideSurfaceLump? PhysCollideSurfaceLump { get; set; }
/// <summary>
/// LUMP_WATEROVERLAYS [50]
/// </summary>
/// TODO: Find definition and implement
// public WaterOverlaysLump? WaterOverlaysLump { get; set; }
/// <summary>
/// LUMP_LIGHTMAPPAGES / LUMP_LEAF_AMBIENT_INDEX_HDR [51]
/// </summary>
public AmbientIndexLump? HDRAmbientIndexLump { get; set; }
/// <summary>
/// LUMP_LIGHTMAPPAGEINFOS / LUMP_LEAF_AMBIENT_INDEX [52]
/// </summary>
public AmbientIndexLump? LDRAmbientIndexLump { get; set; }
/// <summary>
/// LUMP_LIGHTING_HDR [53]
/// </summary>
/// TODO: Find definition and implement
// public LightingHdrLump? LightingHdrLump { get; set; }
/// <summary>
/// LUMP_WORLDLIGHTS_HDR [54]
/// </summary>
public WorldLightsLump? WorldLightsLump { get; set; }
/// <summary>
/// LUMP_LEAF_AMBIENT_LIGHTING_HDR [55]
/// </summary>
public AmbientLightingLump? HDRAmbientLightingLump { get; set; }
/// <summary>
/// LUMP_LEAF_AMBIENT_LIGHTING [56]
/// </summary>
public AmbientLightingLump? LDRAmbientLightingLump { get; set; }
/// <summary>
/// LUMP_XZIPPAKFILE [57]
/// </summary>
/// TODO: Find definition and implement
// public XzipPakFileLump? XzipPakFileLump { get; set; }
/// <summary>
/// LUMP_FACES_HDR [58]
/// </summary>
/// TODO: Find definition and implement
// public FacesHdrLump? FacesHdrLump { get; set; }
/// <summary>
/// LUMP_MAP_FLAGS [59]
/// </summary>
/// TODO: Find definition and implement
// public MapFlagsLump? MapFlagsLump { get; set; }
/// <summary>
/// LUMP_OVERLAY_FADES [60]
/// </summary>
/// TODO: Find definition and implement
// public OverlayFadesLump? OverlayFadesLump { get; set; }
/// <summary>
/// LUMP_OVERLAY_SYSTEM_LEVELS [61]
/// </summary>
/// TODO: Find definition and implement
// public OverlaySystemLevelsLump? OverlaySystemLevelsLump { get; set; }
/// <summary>
/// LUMP_PHYSLEVEL [62]
/// </summary>
/// TODO: Find definition and implement
// public PhysLevelLump? PhysLevelLump { get; set; }
/// <summary>
/// LUMP_DISP_MULTIBLEND [64]
/// </summary>
/// TODO: Find definition and implement
// public DispMultiBlendLump? DispMultiBlendLump { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,33 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/VBSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class VbspHeader
{
/// <summary>
/// BSP file signature
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
/// <summary>
/// BSP file version
/// </summary>
/// <remarks>17,18,19,20,21,22,23,25,27,29</remarks>
public int Version;
/// <summary>
/// Lump directory array
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.VBSP_HEADER_LUMPS)]
public VbspLumpEntry[]? Lumps = new VbspLumpEntry[Constants.VBSP_HEADER_LUMPS];
/// <summary>
/// The map's revision (iteration, version) number.
/// </summary>
public int MapRevision;
}
}

View File

@@ -0,0 +1,99 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The leaves lump contains the leaves of the BSP tree.
///
/// The first entry of this struct is the type of the content
/// of this leaf. It can be one of the predefined values, found
/// in the compiler source codes, and is litte relevant for the
/// actual rendering process. All the more important is the
/// next integer containing the offset into the vis lump. It
/// defines the start of the raw PVS data for this leaf. If this
/// value equals -1, no VIS lists are available for this leaf,
/// usually if the map has been built without the VIS compiler.
/// The next two 16bit integer triples span the bounding box of
/// this leaf. Furthermore, the struct contains an index pointing
/// into the array of marksurfaces loaded from the marksufaces
/// lump as well as the number of consecutive marksurfaces belonging
/// to this leaf. The marksurfaces are looped through during the
/// rendering process and point to the actual faces. The final 4 bytes
/// specify the volume of ambient sounds in Quake, but are unused in
/// GoldSrc.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VbspLeaf
{
/// <summary>
/// Contents enumeration
/// </summary>
public VbspContents Contents;
/// <summary>
/// Cluster this leaf is in
/// </summary>
public short Cluster;
/// <summary>
/// Area this leaf is in and flags
/// </summary>
/// <remarks>area:9, flags:7</remarks>
public short AreaFlags;
/// <summary>
/// For frustum culling
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public short[] Mins = new short[3];
/// <summary>
/// For frustum culling
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public short[] Maxs = new short[3];
/// <summary>
/// Index into leaffaces
/// </summary>
public ushort FirstLeafFace;
/// <summary>
/// Count of leaffaces
/// </summary>
public ushort NumLeafFaces;
/// <summary>
/// Index into leafbrushes
/// </summary>
public ushort FirstLeafBrush;
/// <summary>
/// Count of leafbrushes
/// </summary>
public ushort NumLeafBrushes;
/// <summary>
/// -1 for not in water
/// </summary>
public short LeafWaterDataID;
#region Lump Version 0
/// <summary>
/// Precaculated light info for entities.
/// </summary>
public CompressedLightCube AmbientLighting;
#endregion
#region Lump Version 1+
/// <summary>
/// Padding to 4-byte boundary
/// </summary>
public short Padding;
#endregion
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
public sealed class VbspLeavesLump : Lump
{
/// <summary>
/// Leaves
/// </summary>
public VbspLeaf[]? Leaves { get; set; }
}
}

View File

@@ -1,24 +1,22 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.VBSP
namespace SabreTools.Models.BSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/VBSPFile.h"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Lump
public sealed class VbspLumpEntry : BspLumpEntry
{
public uint Offset;
public uint Length;
/// <summary>
/// Default to zero.
/// Lump format version
/// </summary>
public uint Version;
/// <summary>
/// Default to (char)0, (char)0, (char)0, (char)0.
/// Lump ident code
/// </summary>
/// <remarks>Default to 0, 0, 0, 0</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[]? FourCC;
public byte[]? FourCC = new byte[4];
}
}

View File

@@ -0,0 +1,45 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// A Model, in the terminology of the BSP file format, is a collection
/// of brushes and faces, often called a "bmodel". It should not be
/// confused with the prop models used in Hammer, which are usually
/// called "studiomodels" in the SDK source.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class VbspModel
{
/// <summary>
/// Bounding box
/// </summary>
public Vector3D Mins;
/// <summary>
/// Bounding box
/// </summary>
public Vector3D Maxs;
/// <summary>
/// For sounds or lights
/// </summary>
public Vector3D OriginVector;
/// <summary>
/// Index into nodes
/// </summary>
public int HeadNode;
/// <summary>
/// Index into faces
/// </summary>
public int FirstFaceIndex;
/// <summary>
/// Count of faces
/// </summary>
public int FacesCount;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VbspModelsLump : Lump
{
/// <summary>
/// Model
/// </summary>
public VbspModel[]? Models { get; set; }
}
}

View File

@@ -0,0 +1,39 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// This lump is simple again and contains an array of binary
/// structures, the nodes, which are a major part of the BSP tree.
///
/// Every BSPNODE structure represents a node in the BSP tree and
/// every node equals more or less a division step of the BSP algorithm.
/// Therefore, each node has an index (iPlane) referring to a plane
/// in the plane lump which devides the node into its two child nodes.
/// The childnodes are also stored as indexes. Contrary to the plane
/// index, the node index for the child is signed. If the index is
/// larger than 0, the index indicates a child node. If it is equal
/// to or smaller than zero (no valid array index), the bitwise
/// inversed value of the index gives an index into the leaves lump.
/// Additionally two points (nMins, nMaxs) span the bounding box
/// (AABB, axis aligned bounding box) delimitting the space of the node.
/// Finally firstFace indexes into the face lump and spezifies the
/// first of nFaces surfaces contained in this node.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public class VbspNode : BspNode
{
/// <summary>
/// If all leaves below this node are in the same area, then
/// this is the area index. If not, this is -1.
/// </summary>
public short Area;
/// <summary>
/// Pad to 32 bytes length
/// </summary>
public short Padding;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VbspNodesLump : Lump
{
/// <summary>
/// Nodes
/// </summary>
public VbspNode[]? Nodes { get; set; }
}
}

View File

@@ -0,0 +1,72 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The texinfo lump contains informations about how textures are
/// applied to surfaces. The lump itself is an array of binary data
/// structures.
///
/// This struct is mainly responsible for the calculation of the texture
/// coordinates (vS, fSShift, vT, fTShift). This values determine the
/// position of the texture on the surface. The iMiptex integer refers
/// to the textures in the texture lump and would be the index in an
/// array of BSPMITEX structs. Finally, there are 4 Bytes used for flags.
/// Only one flag is used by the vanilla engine, being 0x1 for disabling
/// lightmaps and subdivision for the surface (used by sky and liquids).
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class VbspTexinfo
{
/// <summary>
/// Texture S-vector
/// </summary>
public Vector3D TextureSVector;
/// <summary>
/// Texture shift in the S direction
/// </summary>
public float TextureSShift;
/// <summary>
/// Texture T-vector
/// </summary>
public Vector3D TextureTVector;
/// <summary>
/// Texture shift in the T direction
/// </summary>
public float TextureTShift;
/// <summary>
/// Lightmap S-vector
/// </summary>
public Vector3D LightmapSVector;
/// <summary>
/// Lightmap shift in the S direction
/// </summary>
public float LightmapSShift;
/// <summary>
/// Lightmap T-vector
/// </summary>
public Vector3D LightmapTVector;
/// <summary>
/// Lightmap shift in the T direction
/// </summary>
public float LightmapTShift;
/// <summary>
/// Texture flags
/// </summary>
public TextureFlag Flags;
/// <summary>
/// Pointer to texture name, size, etc.
/// </summary>
public int TexData;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VbspTexinfoLump : Lump
{
/// <summary>
/// Texinfos
/// </summary>
public VbspTexinfo[]? Texinfos { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// There is a common struct used to represent a point in
/// 3-dimensional space which is used throughout the file
/// spec and the code of the hlbsp project.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Vector3D
{
public float X { get; set; }
public float Y { get; set; }
public float Z { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// This lump simply consists of all vertices of the BSP tree.
/// They are stored as a primitve array of triples of floats.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VerticesLump : Lump
{
/// <summary>
/// Vertices
/// </summary>
public Vector3D[]? Vertices { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
namespace SabreTools.Models.BSP
{
/// <summary>
/// The VIS lump contains data, which is irrelevant to the actual
/// BSP tree, but offers a way to boost up the speed of the
/// renderer significantly. Especially complex maps profit from
/// the use if this data. This lump contains the so-called
/// Potentially Visible Sets (PVS) (also called VIS lists) in the
/// same amout of leaves of the tree, the user can enter (often
/// referred to as VisLeaves). The visiblilty lists are stored as
/// sequences of bitfields, which are run-length encoded.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(GoldSrc)"/>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class VisibilityLump
{
public int NumClusters { get; set; }
/// <remarks>[numclusters][2]</remarks>
public int[,]? ByteOffsets { get; set; }
}
}

View File

@@ -0,0 +1,70 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BSP
{
/// <summary>
/// The worldlights lumps (Lump 15 for LDR and Lump 54 for HDR)
/// contain information on each static light entity in the world,
/// and are used to provide direct lighting for dynamically lit entities.
/// The data is generated by VRAD from the entity lump. VRAD uses
/// information from these lumps instead of referring to light
/// entities from Entity lump.
/// </summary>
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class WorldLight
{
public Vector3D Origin;
public Vector3D Intensity;
/// <summary>
/// For surfaces and spotlights
/// </summary>
public Vector3D Normal;
public int Cluster;
public EmitType EmitType;
public int Style;
/// <summary>
/// Start of penumbra for emit_spotlight
/// </summary>
public float StopDot;
/// <summary>
/// End of penumbra for emit_spotlight
/// </summary>
public float StopDot2;
public float Exponent;
/// <summary>
/// Cutoff distance
/// </summary>
public float Radius;
// falloff for emit_spotlight + emit_point:
// 1 / (constant_attn + linear_attn * dist + quadratic_attn * dist^2)
public float ConstantAttn;
public float LinearAttn;
public float QuadraticAttn;
/// <summary>
/// Uses a combination of the DWL_FLAGS_ defines.
/// </summary>
public int Flags;
public int Texinfo;
/// <summary>
/// Entity that this light it relative to
/// </summary>
public int Owner;
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.BSP
{
/// <see href="https://developer.valvesoftware.com/wiki/BSP_(Source)"/>
public sealed class WorldLightsLump : Lump
{
/// <summary>
/// WorldLights
/// </summary>
public WorldLight[]? WorldLights { get; set; }
}
}

View File

@@ -1,7 +1,7 @@
namespace SabreTools.Models.Compression.MSZIP
namespace SabreTools.Models.Compression.Deflate
{
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
public class DeflateBlockHeader
public class BlockHeader
{
/// <summary>
/// Set if and only if this is the last block of the data set.

View File

@@ -1,4 +1,4 @@
namespace SabreTools.Models.Compression.MSZIP
namespace SabreTools.Models.Compression.Deflate
{
/// <summary>
/// Compression with Huffman codes (BTYPE=01 or BTYPE=02)

View File

@@ -0,0 +1,136 @@
namespace SabreTools.Models.Compression.Deflate
{
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
public static class Constants
{
/// <summary>
/// Bits in base literal/length lookup table
/// </summary>
public const int ZIPLBITS = 9;
/// <summary>
/// Bits in base distance lookup table
/// </summary>
public const int ZIPDBITS = 6;
/// <summary>
/// Maximum bit length of any code
/// </summary>
public const int ZIPBMAX = 16;
/// <summary>
/// Maximum number of codes in any set
/// </summary>
public const int ZIPN_MAX = 288;
#region Fixed Huffman Codes
/// <summary>
/// Fixed Huffman code lengths for the literal / length alphabet
/// </summary>
public static readonly uint[] FixedLiteralLengths =
[
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8,
];
/// <summary>
/// Fixed Huffman distance codes for the literal / length alphabet
/// </summary>
public static readonly uint[] FixedDistanceCodes =
[
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5,
];
#endregion
#region Literal and Length Alphabets
/// <summary>
/// Extra bits for distance codes
/// </summary>
public static readonly ushort[] DistanceExtraBits =
[
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12, 13, 13
];
/// <summary>
/// Copy offsets for distance codes 0..29
/// </summary>
public static readonly ushort[] DistanceOffsets =
[
1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
];
/// <summary>
/// Extra bits for literal codes 257..285
/// </summary>
public static readonly ushort[] LiteralExtraBits =
[
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 4, 4, 5, 5, 5, 5, 0,
];
/// <summary>
/// Copy lengths for literal codes 257..285
/// </summary>
public static readonly ushort[] LiteralLengths =
[
3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
67, 83, 99, 115, 131, 163, 195, 227, 258,
];
/// <summary>
/// Order of the bit length code lengths
/// </summary>
public static readonly byte[] BitLengthOrder =
[
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
];
#endregion
}
}

View File

@@ -1,4 +1,4 @@
namespace SabreTools.Models.Compression.MSZIP
namespace SabreTools.Models.Compression.Deflate
{
/// <summary>
/// Base class for all data headers (BTYPE=00, BTYPE=01, or BTYPE=02)

View File

@@ -1,4 +1,4 @@
namespace SabreTools.Models.Compression.MSZIP
namespace SabreTools.Models.Compression.Deflate
{
/// <summary>
/// Compression with dynamic Huffman codes (BTYPE=10)

View File

@@ -1,5 +1,6 @@
namespace SabreTools.Models.Compression.MSZIP
namespace SabreTools.Models.Compression.Deflate
{
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
public enum CompressionType : byte
{
/// <summary>

View File

@@ -0,0 +1,24 @@
namespace SabreTools.Models.Compression.Deflate
{
/// <summary>
/// Compression with fixed Huffman codes (BTYPE=01)
/// </summary>
/// <see href="https://interoperability.blob.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
public class FixedCompressedDataHeader : CompressedDataHeader
{
#region Properties
/// <summary>
/// Huffman code lengths for the literal / length alphabet
/// </summary>
public override uint[]? LiteralLengths => Constants.FixedLiteralLengths;
/// <summary>
/// Huffman distance codes for the literal / length alphabet
/// </summary>
public override uint[]? DistanceCodes => Constants.FixedDistanceCodes;
#endregion
}
}

View File

@@ -1,4 +1,4 @@
namespace SabreTools.Models.Compression.MSZIP
namespace SabreTools.Models.Compression.Deflate
{
/// <summary>
/// Non-compressed blocks (BTYPE=00)

View File

@@ -8,73 +8,6 @@ namespace SabreTools.Models.Compression.MSZIP
/// </summary>
public const ushort ZIPWSIZE = 0x8000;
/// <summary>
/// Bits in base literal/length lookup table
/// </summary>
public const int ZIPLBITS = 9;
/// <summary>
/// Bits in base distance lookup table
/// </summary>
public const int ZIPDBITS = 6;
/// <summary>
/// Maximum bit length of any code
/// </summary>
public const int ZIPBMAX = 16;
/// <summary>
/// Maximum number of codes in any set
/// </summary>
public const int ZIPN_MAX = 288;
#region THOSE_ZIP_CONSTS
/// <summary>
/// Order of the bit length code lengths
/// </summary>
public static readonly byte[] BitLengthOrder =
[
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
];
/// <summary>
/// Copy lengths for literal codes 257..285
/// </summary>
public static readonly ushort[] CopyLengths =
[
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
];
/// <summary>
/// Extra bits for literal codes 257..285
/// </summary>
/// <remarks>99 == invalid</remarks>
public static readonly ushort[] LiteralExtraBits =
[
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
4, 5, 5, 5, 5, 0, 99, 99
];
/// <summary>
/// Copy offsets for distance codes 0..29
/// </summary>
public static readonly ushort[] CopyOffsets =
[
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
];
/// <summary>
/// Extra bits for distance codes
/// </summary>
public static readonly ushort[] DistanceExtraBits =
[
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
10, 11, 11, 12, 12, 13, 13
];
/// <summary>
/// And'ing with Zipmask[n] masks the lower n bits
/// </summary>
@@ -83,7 +16,5 @@ namespace SabreTools.Models.Compression.MSZIP
0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
];
#endregion
}
}

View File

@@ -15,12 +15,12 @@ namespace SabreTools.Models.Compression.MSZIP
/// <summary>
/// Deflate block (RFC-1951) header
/// </summary>
public DeflateBlockHeader? Header { get; set; }
public Deflate.BlockHeader? Header { get; set; }
/// <summary>
/// Compression-specific data header
/// </summary>
public DataHeader? DataHeader { get; set; }
public Deflate.DataHeader? DataHeader { get; set; }
/// <summary>
/// MSZIP data

Some files were not shown because too many files have changed in this diff Show More