summaryrefslogtreecommitdiff
path: root/public/bspfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'public/bspfile.h')
-rw-r--r--public/bspfile.h1156
1 files changed, 1156 insertions, 0 deletions
diff --git a/public/bspfile.h b/public/bspfile.h
new file mode 100644
index 0000000..d4c3a05
--- /dev/null
+++ b/public/bspfile.h
@@ -0,0 +1,1156 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Defines and structures for the BSP file format.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BSPFILE_H
+#define BSPFILE_H
+#pragma once
+
+#ifndef MATHLIB_H
+#include "mathlib/mathlib.h"
+#endif
+
+#include "datamap.h"
+#include "mathlib/bumpvects.h"
+#include "mathlib/compressed_light_cube.h"
+
+// little-endian "VBSP"
+#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'V')
+
+// MINBSPVERSION is the minimum acceptable version. The engine will load MINBSPVERSION through BSPVERSION
+#define MINBSPVERSION 19
+#define BSPVERSION 20
+
+
+// This needs to match the value in gl_lightmap.h
+// Need to dynamically allocate the weights and light values in radial_t to make this variable.
+#define MAX_BRUSH_LIGHTMAP_DIM_WITHOUT_BORDER 32
+// This is one more than what vbsp cuts for to allow for rounding errors
+#define MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER 35
+
+// We can have larger lightmaps on displacements
+#define MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER 125
+#define MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER 128
+
+
+// This is the actual max.. (change if you change the brush lightmap dim or disp lightmap dim
+#define MAX_LIGHTMAP_DIM_WITHOUT_BORDER MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER
+#define MAX_LIGHTMAP_DIM_INCLUDING_BORDER MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER
+
+#define MAX_LIGHTSTYLES 64
+
+
+// upper design bounds
+#define MIN_MAP_DISP_POWER 2 // Minimum and maximum power a displacement can be.
+#define MAX_MAP_DISP_POWER 4
+
+// Max # of neighboring displacement touching a displacement's corner.
+#define MAX_DISP_CORNER_NEIGHBORS 4
+
+#define NUM_DISP_POWER_VERTS(power) ( ((1 << (power)) + 1) * ((1 << (power)) + 1) )
+#define NUM_DISP_POWER_TRIS(power) ( (1 << (power)) * (1 << (power)) * 2 )
+
+#if !defined( BSP_USE_LESS_MEMORY )
+// Common limits
+// leaffaces, leafbrushes, planes, and verts are still bounded by
+// 16 bit short limits
+#define MAX_MAP_MODELS 1024
+#define MAX_MAP_BRUSHES 8192
+#define MAX_MAP_ENTITIES 8192
+#define MAX_MAP_TEXINFO 12288
+#define MAX_MAP_TEXDATA 2048
+#define MAX_MAP_DISPINFO 2048
+#define MAX_MAP_DISP_VERTS ( MAX_MAP_DISPINFO * ((1<<MAX_MAP_DISP_POWER)+1) * ((1<<MAX_MAP_DISP_POWER)+1) )
+#define MAX_MAP_DISP_TRIS ( (1 << MAX_MAP_DISP_POWER) * (1 << MAX_MAP_DISP_POWER) * 2 )
+#define MAX_DISPVERTS NUM_DISP_POWER_VERTS( MAX_MAP_DISP_POWER )
+#define MAX_DISPTRIS NUM_DISP_POWER_TRIS( MAX_MAP_DISP_POWER )
+#define MAX_MAP_AREAS 256
+#define MAX_MAP_AREA_BYTES (MAX_MAP_AREAS/8)
+#define MAX_MAP_AREAPORTALS 1024
+// Planes come in pairs, thus an even number.
+#define MAX_MAP_PLANES 65536
+#define MAX_MAP_NODES 65536
+#define MAX_MAP_BRUSHSIDES 65536
+#define MAX_MAP_LEAFS 65536
+#define MAX_MAP_VERTS 65536
+#define MAX_MAP_VERTNORMALS 256000
+#define MAX_MAP_VERTNORMALINDICES 256000
+#define MAX_MAP_FACES 65536
+#define MAX_MAP_LEAFFACES 65536
+#define MAX_MAP_LEAFBRUSHES 65536
+#define MAX_MAP_PORTALS 65536
+#define MAX_MAP_CLUSTERS 65536
+#define MAX_MAP_LEAFWATERDATA 32768
+#define MAX_MAP_PORTALVERTS 128000
+#define MAX_MAP_EDGES 256000
+#define MAX_MAP_SURFEDGES 512000
+#define MAX_MAP_LIGHTING 0x1000000
+#define MAX_MAP_VISIBILITY 0x1000000 // increased BSPVERSION 7
+#define MAX_MAP_TEXTURES 1024
+#define MAX_MAP_WORLDLIGHTS 8192
+#define MAX_MAP_CUBEMAPSAMPLES 1024
+#define MAX_MAP_OVERLAYS 512
+#define MAX_MAP_WATEROVERLAYS 16384
+#define MAX_MAP_TEXDATA_STRING_DATA 256000
+#define MAX_MAP_TEXDATA_STRING_TABLE 65536
+// this is stuff for trilist/tristrips, etc.
+#define MAX_MAP_PRIMITIVES 32768
+#define MAX_MAP_PRIMVERTS 65536
+#define MAX_MAP_PRIMINDICES 65536
+
+#else
+
+// Xbox 360 - Force static arrays to be very small
+#define MAX_MAP_MODELS 2
+#define MAX_MAP_BRUSHES 2
+#define MAX_MAP_ENTITIES 2
+#define MAX_MAP_TEXINFO 2
+#define MAX_MAP_TEXDATA 2
+#define MAX_MAP_DISPINFO 2
+#define MAX_MAP_DISP_VERTS ( MAX_MAP_DISPINFO * ((1<<MAX_MAP_DISP_POWER)+1) * ((1<<MAX_MAP_DISP_POWER)+1) )
+#define MAX_MAP_DISP_TRIS ( (1 << MAX_MAP_DISP_POWER) * (1 << MAX_MAP_DISP_POWER) * 2 )
+#define MAX_DISPVERTS NUM_DISP_POWER_VERTS( MAX_MAP_DISP_POWER )
+#define MAX_DISPTRIS NUM_DISP_POWER_TRIS( MAX_MAP_DISP_POWER )
+#define MAX_MAP_AREAS 2
+#define MAX_MAP_AREA_BYTES 2
+#define MAX_MAP_AREAPORTALS 2
+#define MAX_MAP_PLANES 2
+#define MAX_MAP_NODES 2
+#define MAX_MAP_BRUSHSIDES 2
+#define MAX_MAP_LEAFS 2
+#define MAX_MAP_VERTS 2
+#define MAX_MAP_VERTNORMALS 2
+#define MAX_MAP_VERTNORMALINDICES 2
+#define MAX_MAP_FACES 2
+#define MAX_MAP_LEAFFACES 2
+#define MAX_MAP_LEAFBRUSHES 2
+#define MAX_MAP_PORTALS 2
+#define MAX_MAP_CLUSTERS 2
+#define MAX_MAP_LEAFWATERDATA 2
+#define MAX_MAP_PORTALVERTS 2
+#define MAX_MAP_EDGES 2
+#define MAX_MAP_SURFEDGES 2
+#define MAX_MAP_LIGHTING 2
+#define MAX_MAP_VISIBILITY 2
+#define MAX_MAP_TEXTURES 2
+#define MAX_MAP_WORLDLIGHTS 2
+#define MAX_MAP_CUBEMAPSAMPLES 2
+#define MAX_MAP_OVERLAYS 2
+#define MAX_MAP_WATEROVERLAYS 2
+#define MAX_MAP_TEXDATA_STRING_DATA 2
+#define MAX_MAP_TEXDATA_STRING_TABLE 2
+#define MAX_MAP_PRIMITIVES 2
+#define MAX_MAP_PRIMVERTS 2
+#define MAX_MAP_PRIMINDICES 2
+
+#endif // BSP_USE_LESS_MEMORY
+
+// key / value pair sizes
+#define MAX_KEY 32
+#define MAX_VALUE 1024
+
+
+// ------------------------------------------------------------------------------------------------ //
+// Displacement neighbor rules
+// ------------------------------------------------------------------------------------------------ //
+//
+// Each displacement is considered to be in its own space:
+//
+// NEIGHBOREDGE_TOP
+//
+// 1 --- 2
+// | |
+// NEIGHBOREDGE_LEFT | | NEIGHBOREDGE_RIGHT
+// | |
+// 0 --- 3
+//
+// NEIGHBOREDGE_BOTTOM
+//
+//
+// Edge edge of a displacement can have up to two neighbors. If it only has one neighbor
+// and the neighbor fills the edge, then SubNeighbor 0 uses CORNER_TO_CORNER (and SubNeighbor 1
+// is undefined).
+//
+// CORNER_TO_MIDPOINT means that it spans [bottom edge,midpoint] or [left edge,midpoint] depending
+// on which edge you're on.
+//
+// MIDPOINT_TO_CORNER means that it spans [midpoint,top edge] or [midpoint,right edge] depending
+// on which edge you're on.
+//
+// Here's an illustration (where C2M=CORNER_TO_MIDPOINT and M2C=MIDPOINT_TO_CORNER
+//
+//
+// C2M M2C
+//
+// 1 --------------> x --------------> 2
+//
+// ^ ^
+// | |
+// | |
+// M2C | | M2C
+// | |
+// | |
+//
+// x x x
+//
+// ^ ^
+// | |
+// | |
+// C2M | | C2M
+// | |
+// | |
+//
+// 0 --------------> x --------------> 3
+//
+// C2M M2C
+//
+//
+// The CHILDNODE_ defines can be used to refer to a node's child nodes (this is for when you're
+// recursing into the node tree inside a displacement):
+//
+// ---------
+// | | |
+// | 1 | 0 |
+// | | |
+// |---x---|
+// | | |
+// | 2 | 3 |
+// | | |
+// ---------
+//
+// ------------------------------------------------------------------------------------------------ //
+
+// These can be used to index g_ChildNodeIndexMul.
+enum
+{
+ CHILDNODE_UPPER_RIGHT=0,
+ CHILDNODE_UPPER_LEFT=1,
+ CHILDNODE_LOWER_LEFT=2,
+ CHILDNODE_LOWER_RIGHT=3
+};
+
+
+// Corner indices. Used to index m_CornerNeighbors.
+enum
+{
+ CORNER_LOWER_LEFT=0,
+ CORNER_UPPER_LEFT=1,
+ CORNER_UPPER_RIGHT=2,
+ CORNER_LOWER_RIGHT=3
+};
+
+
+// These edge indices must match the edge indices of the CCoreDispSurface.
+enum
+{
+ NEIGHBOREDGE_LEFT=0,
+ NEIGHBOREDGE_TOP=1,
+ NEIGHBOREDGE_RIGHT=2,
+ NEIGHBOREDGE_BOTTOM=3
+};
+
+
+// These denote where one dispinfo fits on another.
+// Note: tables are generated based on these indices so make sure to update
+// them if these indices are changed.
+typedef enum
+{
+ CORNER_TO_CORNER=0,
+ CORNER_TO_MIDPOINT=1,
+ MIDPOINT_TO_CORNER=2
+} NeighborSpan;
+
+
+// These define relative orientations of displacement neighbors.
+typedef enum
+{
+ ORIENTATION_CCW_0=0,
+ ORIENTATION_CCW_90=1,
+ ORIENTATION_CCW_180=2,
+ ORIENTATION_CCW_270=3
+} NeighborOrientation;
+
+
+//=============================================================================
+
+enum
+{
+ LUMP_ENTITIES = 0, // *
+ LUMP_PLANES = 1, // *
+ LUMP_TEXDATA = 2, // *
+ LUMP_VERTEXES = 3, // *
+ LUMP_VISIBILITY = 4, // *
+ LUMP_NODES = 5, // *
+ LUMP_TEXINFO = 6, // *
+ LUMP_FACES = 7, // *
+ LUMP_LIGHTING = 8, // *
+ LUMP_OCCLUSION = 9,
+ LUMP_LEAFS = 10, // *
+ LUMP_FACEIDS = 11,
+ LUMP_EDGES = 12, // *
+ LUMP_SURFEDGES = 13, // *
+ LUMP_MODELS = 14, // *
+ LUMP_WORLDLIGHTS = 15, //
+ LUMP_LEAFFACES = 16, // *
+ LUMP_LEAFBRUSHES = 17, // *
+ LUMP_BRUSHES = 18, // *
+ LUMP_BRUSHSIDES = 19, // *
+ LUMP_AREAS = 20, // *
+ LUMP_AREAPORTALS = 21, // *
+ LUMP_UNUSED0 = 22,
+ LUMP_UNUSED1 = 23,
+ LUMP_UNUSED2 = 24,
+ LUMP_UNUSED3 = 25,
+ LUMP_DISPINFO = 26,
+ LUMP_ORIGINALFACES = 27,
+ LUMP_PHYSDISP = 28,
+ LUMP_PHYSCOLLIDE = 29,
+ LUMP_VERTNORMALS = 30,
+ LUMP_VERTNORMALINDICES = 31,
+ LUMP_DISP_LIGHTMAP_ALPHAS = 32,
+ LUMP_DISP_VERTS = 33, // CDispVerts
+ LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS = 34, // For each displacement
+ // For each lightmap sample
+ // byte for index
+ // if 255, then index = next byte + 255
+ // 3 bytes for barycentric coordinates
+ // The game lump is a method of adding game-specific lumps
+ // FIXME: Eventually, all lumps could use the game lump system
+ LUMP_GAME_LUMP = 35,
+ LUMP_LEAFWATERDATA = 36,
+ LUMP_PRIMITIVES = 37,
+ LUMP_PRIMVERTS = 38,
+ LUMP_PRIMINDICES = 39,
+ // A pak file can be embedded in a .bsp now, and the file system will search the pak
+ // file first for any referenced names, before deferring to the game directory
+ // file system/pak files and finally the base directory file system/pak files.
+ LUMP_PAKFILE = 40,
+ LUMP_CLIPPORTALVERTS = 41,
+ // A map can have a number of cubemap entities in it which cause cubemap renders
+ // to be taken after running vrad.
+ LUMP_CUBEMAPS = 42,
+ LUMP_TEXDATA_STRING_DATA = 43,
+ LUMP_TEXDATA_STRING_TABLE = 44,
+ LUMP_OVERLAYS = 45,
+ LUMP_LEAFMINDISTTOWATER = 46,
+ LUMP_FACE_MACRO_TEXTURE_INFO = 47,
+ LUMP_DISP_TRIS = 48,
+ LUMP_PHYSCOLLIDESURFACE = 49, // deprecated. We no longer use win32-specific havok compression on terrain
+ LUMP_WATEROVERLAYS = 50,
+ LUMP_LEAF_AMBIENT_INDEX_HDR = 51, // index of LUMP_LEAF_AMBIENT_LIGHTING_HDR
+ LUMP_LEAF_AMBIENT_INDEX = 52, // index of LUMP_LEAF_AMBIENT_LIGHTING
+
+ // optional lumps for HDR
+ LUMP_LIGHTING_HDR = 53,
+ LUMP_WORLDLIGHTS_HDR = 54,
+ LUMP_LEAF_AMBIENT_LIGHTING_HDR = 55, // NOTE: this data overrides part of the data stored in LUMP_LEAFS.
+ LUMP_LEAF_AMBIENT_LIGHTING = 56, // NOTE: this data overrides part of the data stored in LUMP_LEAFS.
+
+ LUMP_XZIPPAKFILE = 57, // deprecated. xbox 1: xzip version of pak file
+ LUMP_FACES_HDR = 58, // HDR maps may have different face data.
+ LUMP_MAP_FLAGS = 59, // extended level-wide flags. not present in all levels
+ LUMP_OVERLAY_FADES = 60, // Fade distances for overlays
+};
+
+
+// Lumps that have versions are listed here
+enum
+{
+ LUMP_LIGHTING_VERSION = 1,
+ LUMP_FACES_VERSION = 1,
+ LUMP_OCCLUSION_VERSION = 2,
+ LUMP_LEAFS_VERSION = 1,
+ LUMP_LEAF_AMBIENT_LIGHTING_VERSION = 1,
+};
+
+
+#define HEADER_LUMPS 64
+
+#include "zip_uncompressed.h"
+
+struct lump_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int fileofs, filelen;
+ int version; // default to zero
+ // this field was char fourCC[4] previously, but was unused, favoring the LUMP IDs above instead. It has been
+ // repurposed for compression. 0 implies the lump is not compressed.
+ int uncompressedSize; // default to zero
+};
+
+
+struct dheader_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int ident;
+ int version;
+ lump_t lumps[HEADER_LUMPS];
+ int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6)
+};
+
+// level feature flags
+#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_NONHDR 0x00000001 // was processed by vrad with -staticproplighting, no hdr data
+#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_HDR 0x00000002 // was processed by vrad with -staticproplighting, in hdr
+
+struct dflagslump_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ uint32 m_LevelFlags; // LVLFLAGS_xxx
+};
+
+struct lumpfileheader_t
+{
+ int lumpOffset;
+ int lumpID;
+ int lumpVersion;
+ int lumpLength;
+ int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6)
+};
+
+struct dgamelumpheader_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int lumpCount;
+
+ // dgamelump_t follow this
+};
+
+// This is expected to be a four-CC code ('lump')
+typedef int GameLumpId_t;
+
+// game lump is compressed, filelen reflects original size
+// use next entry fileofs to determine actual disk lump compressed size
+// compression stage ensures a terminal null dictionary entry
+#define GAMELUMPFLAG_COMPRESSED 0x0001
+
+struct dgamelump_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ GameLumpId_t id;
+ unsigned short flags;
+ unsigned short version;
+ int fileofs;
+ int filelen;
+};
+
+extern int g_MapRevision;
+
+struct dmodel_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ Vector mins, maxs;
+ Vector origin; // for sounds or lights
+ int headnode;
+ int firstface, numfaces; // submodels just draw faces without walking the bsp tree
+};
+
+struct dphysmodel_t
+{
+ DECLARE_BYTESWAP_DATADESC()
+ int modelIndex;
+ int dataSize;
+ int keydataSize;
+ int solidCount;
+};
+
+// contains the binary blob for each displacement surface's virtual hull
+struct dphysdisp_t
+{
+ DECLARE_BYTESWAP_DATADESC()
+ unsigned short numDisplacements;
+ //unsigned short dataSize[numDisplacements];
+};
+
+struct dvertex_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ Vector point;
+};
+
+// planes (x&~1) and (x&~1)+1 are always opposites
+struct dplane_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ Vector normal;
+ float dist;
+ int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
+};
+
+#ifndef BSPFLAGS_H
+#include "bspflags.h"
+#endif
+
+struct dnode_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int planenum;
+ int children[2]; // negative numbers are -(leafs+1), not nodes
+ short mins[3]; // for frustom culling
+ short maxs[3];
+ unsigned short firstface;
+ unsigned short numfaces; // counting both sides
+ short area; // If all leaves below this node are in the same area, then
+ // this is the area index. If not, this is -1.
+};
+
+typedef struct texinfo_s
+{
+ DECLARE_BYTESWAP_DATADESC();
+ float textureVecsTexelsPerWorldUnits[2][4]; // [s/t][xyz offset]
+ float lightmapVecsLuxelsPerWorldUnits[2][4]; // [s/t][xyz offset] - length is in units of texels/area
+ int flags; // miptex flags + overrides
+ int texdata; // Pointer to texture name, size, etc.
+} texinfo_t;
+
+#define TEXTURE_NAME_LENGTH 128 // changed from 64 BSPVERSION 8
+
+struct dtexdata_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ Vector reflectivity;
+ int nameStringTableID; // index into g_StringTable for the texture name
+ int width, height; // source image
+ int view_width, view_height; //
+};
+
+
+//-----------------------------------------------------------------------------
+// Occluders are simply polygons
+//-----------------------------------------------------------------------------
+// Flags field of doccluderdata_t
+enum
+{
+ OCCLUDER_FLAGS_INACTIVE = 0x1,
+};
+
+struct doccluderdata_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int flags;
+ int firstpoly; // index into doccluderpolys
+ int polycount;
+ Vector mins;
+ Vector maxs;
+ int area;
+};
+
+struct doccluderdataV1_t
+{
+ int flags;
+ int firstpoly; // index into doccluderpolys
+ int polycount;
+ Vector mins;
+ Vector maxs;
+};
+
+struct doccluderpolydata_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int firstvertexindex; // index into doccludervertindices
+ int vertexcount;
+ int planenum;
+};
+
+
+// NOTE: see the section above titled "displacement neighbor rules".
+struct CDispSubNeighbor
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short GetNeighborIndex() const { return m_iNeighbor; }
+ NeighborSpan GetSpan() const { return (NeighborSpan)m_Span; }
+ NeighborSpan GetNeighborSpan() const { return (NeighborSpan)m_NeighborSpan; }
+ NeighborOrientation GetNeighborOrientation() const { return (NeighborOrientation)m_NeighborOrientation; }
+
+ bool IsValid() const { return m_iNeighbor != 0xFFFF; }
+ void SetInvalid() { m_iNeighbor = 0xFFFF; }
+
+
+public:
+ unsigned short m_iNeighbor; // This indexes into ddispinfos.
+ // 0xFFFF if there is no neighbor here.
+
+ unsigned char m_NeighborOrientation; // (CCW) rotation of the neighbor wrt this displacement.
+
+ // These use the NeighborSpan type.
+ unsigned char m_Span; // Where the neighbor fits onto this side of our displacement.
+ unsigned char m_NeighborSpan; // Where we fit onto our neighbor.
+};
+
+
+// NOTE: see the section above titled "displacement neighbor rules".
+class CDispNeighbor
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ void SetInvalid() { m_SubNeighbors[0].SetInvalid(); m_SubNeighbors[1].SetInvalid(); }
+
+ // Returns false if there isn't anything touching this edge.
+ bool IsValid() { return m_SubNeighbors[0].IsValid() || m_SubNeighbors[1].IsValid(); }
+
+
+public:
+ // Note: if there is a neighbor that fills the whole side (CORNER_TO_CORNER),
+ // then it will always be in CDispNeighbor::m_Neighbors[0]
+ CDispSubNeighbor m_SubNeighbors[2];
+};
+
+
+class CDispCornerNeighbors
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ void SetInvalid() { m_nNeighbors = 0; }
+
+
+public:
+ unsigned short m_Neighbors[MAX_DISP_CORNER_NEIGHBORS]; // indices of neighbors.
+ unsigned char m_nNeighbors;
+};
+
+
+class CDispVert
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ Vector m_vVector; // Vector field defining displacement volume.
+ float m_flDist; // Displacement distances.
+ float m_flAlpha; // "per vertex" alpha values.
+};
+
+#define DISPTRI_TAG_SURFACE (1<<0)
+#define DISPTRI_TAG_WALKABLE (1<<1)
+#define DISPTRI_TAG_BUILDABLE (1<<2)
+#define DISPTRI_FLAG_SURFPROP1 (1<<3)
+#define DISPTRI_FLAG_SURFPROP2 (1<<4)
+#define DISPTRI_TAG_REMOVE (1<<5)
+
+class CDispTri
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short m_uiTags; // Displacement triangle tags.
+};
+
+class ddispinfo_t
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ int NumVerts() const { return NUM_DISP_POWER_VERTS(power); }
+ int NumTris() const { return NUM_DISP_POWER_TRIS(power); }
+
+public:
+ Vector startPosition; // start position used for orientation -- (added BSPVERSION 6)
+ int m_iDispVertStart; // Index into LUMP_DISP_VERTS.
+ int m_iDispTriStart; // Index into LUMP_DISP_TRIS.
+
+ int power; // power - indicates size of map (2^power + 1)
+ int minTess; // minimum tesselation allowed
+ float smoothingAngle; // lighting smoothing angle
+ int contents; // surface contents
+
+ unsigned short m_iMapFace; // Which map face this displacement comes from.
+
+ int m_iLightmapAlphaStart; // Index into ddisplightmapalpha.
+ // The count is m_pParent->lightmapTextureSizeInLuxels[0]*m_pParent->lightmapTextureSizeInLuxels[1].
+
+ int m_iLightmapSamplePositionStart; // Index into LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS.
+
+ CDispNeighbor m_EdgeNeighbors[4]; // Indexed by NEIGHBOREDGE_ defines.
+ CDispCornerNeighbors m_CornerNeighbors[4]; // Indexed by CORNER_ defines.
+
+ enum unnamed { ALLOWEDVERTS_SIZE = PAD_NUMBER( MAX_DISPVERTS, 32 ) / 32 };
+ unsigned long m_AllowedVerts[ALLOWEDVERTS_SIZE]; // This is built based on the layout and sizes of our neighbors
+ // and tells us which vertices are allowed to be active.
+};
+
+
+// note that edge 0 is never used, because negative edge nums are used for
+// counterclockwise use of the edge in a face
+struct dedge_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short v[2]; // vertex numbers
+};
+
+#define MAXLIGHTMAPS 4
+
+enum dprimitive_type
+{
+ PRIM_TRILIST=0,
+ PRIM_TRISTRIP=1,
+};
+
+struct dprimitive_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned char type;
+ unsigned short firstIndex;
+ unsigned short indexCount;
+ unsigned short firstVert;
+ unsigned short vertCount;
+};
+
+struct dprimvert_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ Vector pos;
+};
+
+struct dface_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short planenum;
+ byte side; // faces opposite to the node's plane direction
+ byte onNode; // 1 of on node, 0 if in leaf
+
+ int firstedge; // we must support > 64k edges
+ short numedges;
+ short texinfo;
+ // This is a union under the assumption that a fog volume boundary (ie. water surface)
+ // isn't a displacement map.
+ // FIXME: These should be made a union with a flags or type field for which one it is
+ // if we can add more to this.
+// union
+// {
+ short dispinfo;
+ // This is only for surfaces that are the boundaries of fog volumes
+ // (ie. water surfaces)
+ // All of the rest of the surfaces can look at their leaf to find out
+ // what fog volume they are in.
+ short surfaceFogVolumeID;
+// };
+
+ // lighting info
+ byte styles[MAXLIGHTMAPS];
+ int lightofs; // start of [numstyles*surfsize] samples
+ float area;
+
+ // TODO: make these unsigned chars?
+ int m_LightmapTextureMinsInLuxels[2];
+ int m_LightmapTextureSizeInLuxels[2];
+
+ int origFace; // reference the original face this face was derived from
+
+
+public:
+
+ unsigned short GetNumPrims() const;
+ void SetNumPrims( unsigned short nPrims );
+ bool AreDynamicShadowsEnabled();
+ void SetDynamicShadowsEnabled( bool bEnabled );
+
+ // non-polygon primitives (strips and lists)
+private:
+ unsigned short m_NumPrims; // Top bit, if set, disables shadows on this surface (this is why there are accessors).
+
+public:
+ unsigned short firstPrimID;
+
+ unsigned int smoothingGroups;
+};
+
+
+inline unsigned short dface_t::GetNumPrims() const
+{
+ return m_NumPrims & 0x7FFF;
+}
+
+inline void dface_t::SetNumPrims( unsigned short nPrims )
+{
+ Assert( (nPrims & 0x8000) == 0 );
+ m_NumPrims &= ~0x7FFF;
+ m_NumPrims |= (nPrims & 0x7FFF);
+}
+
+inline bool dface_t::AreDynamicShadowsEnabled()
+{
+ return (m_NumPrims & 0x8000) == 0;
+}
+
+inline void dface_t::SetDynamicShadowsEnabled( bool bEnabled )
+{
+ if ( bEnabled )
+ m_NumPrims &= ~0x8000;
+ else
+ m_NumPrims |= 0x8000;
+}
+
+struct dfaceid_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short hammerfaceid;
+};
+
+
+// NOTE: Only 7-bits stored!!!
+#define LEAF_FLAGS_SKY 0x01 // This leaf has 3D sky in its PVS
+#define LEAF_FLAGS_RADIAL 0x02 // This leaf culled away some portals due to radial vis
+#define LEAF_FLAGS_SKY2D 0x04 // This leaf has 2D sky in its PVS
+
+#if defined( _X360 )
+#pragma bitfield_order( push, lsb_to_msb )
+#endif
+#pragma warning( disable:4201 ) // C4201: nonstandard extension used: nameless struct/union
+struct dleaf_version_0_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int contents; // OR of all brushes (not needed?)
+
+ short cluster;
+
+ BEGIN_BITFIELD( bf );
+ short area:9;
+ short flags:7; // Per leaf flags.
+ END_BITFIELD();
+
+ short mins[3]; // for frustum culling
+ short maxs[3];
+
+ unsigned short firstleafface;
+ unsigned short numleaffaces;
+
+ unsigned short firstleafbrush;
+ unsigned short numleafbrushes;
+ short leafWaterDataID; // -1 for not in water
+
+ // Precaculated light info for entities.
+ CompressedLightCube m_AmbientLighting;
+};
+
+// version 1
+struct dleaf_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int contents; // OR of all brushes (not needed?)
+
+ short cluster;
+
+ BEGIN_BITFIELD( bf );
+ short area:9;
+ short flags:7; // Per leaf flags.
+ END_BITFIELD();
+
+ short mins[3]; // for frustum culling
+ short maxs[3];
+
+ unsigned short firstleafface;
+ unsigned short numleaffaces;
+
+ unsigned short firstleafbrush;
+ unsigned short numleafbrushes;
+ short leafWaterDataID; // -1 for not in water
+
+ // NOTE: removed this for version 1 and moved into separate lump "LUMP_LEAF_AMBIENT_LIGHTING" or "LUMP_LEAF_AMBIENT_LIGHTING_HDR"
+ // Precaculated light info for entities.
+// CompressedLightCube m_AmbientLighting;
+};
+#pragma warning( default:4201 ) // C4201: nonstandard extension used: nameless struct/union
+#if defined( _X360 )
+#pragma bitfield_order( pop )
+#endif
+
+// each leaf contains N samples of the ambient lighting
+// each sample contains a cube of ambient light projected on to each axis
+// and a sampling position encoded as a 0.8 fraction (mins=0,maxs=255) of the leaf's bounding box
+struct dleafambientlighting_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ CompressedLightCube cube;
+ byte x; // fixed point fraction of leaf bounds
+ byte y; // fixed point fraction of leaf bounds
+ byte z; // fixed point fraction of leaf bounds
+ byte pad; // unused
+};
+
+struct dleafambientindex_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+
+ unsigned short ambientSampleCount;
+ unsigned short firstAmbientSample;
+};
+
+struct dbrushside_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short planenum; // facing out of the leaf
+ short texinfo;
+ short dispinfo; // displacement info (BSPVERSION 7)
+ short bevel; // is the side a bevel plane? (BSPVERSION 7)
+};
+
+struct dbrush_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int firstside;
+ int numsides;
+ int contents;
+};
+
+#define ANGLE_UP -1
+#define ANGLE_DOWN -2
+
+
+// the visibility lump consists of a header with a count, then
+// byte offsets for the PVS and PHS of each cluster, then the raw
+// compressed bit vectors
+#define DVIS_PVS 0
+#define DVIS_PAS 1
+struct dvis_t
+{
+ int numclusters;
+ int bitofs[8][2]; // bitofs[numclusters][2]
+};
+
+// each area has a list of portals that lead into other areas
+// when portals are closed, other areas may not be visible or
+// hearable even if the vis info says that it should be
+struct dareaportal_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ unsigned short m_PortalKey; // Entities have a key called portalnumber (and in vbsp a variable
+ // called areaportalnum) which is used
+ // to bind them to the area portals by comparing with this value.
+
+ unsigned short otherarea; // The area this portal looks into.
+
+ unsigned short m_FirstClipPortalVert; // Portal geometry.
+ unsigned short m_nClipPortalVerts;
+
+ int planenum;
+};
+
+
+struct darea_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int numareaportals;
+ int firstareaportal;
+};
+
+struct dleafwaterdata_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ float surfaceZ;
+ float minZ;
+ short surfaceTexInfoID;
+};
+
+class CFaceMacroTextureInfo
+{
+public:
+ DECLARE_BYTESWAP_DATADESC();
+ // This looks up into g_TexDataStringTable, which looks up into g_TexDataStringData.
+ // 0xFFFF if the face has no macro texture.
+ unsigned short m_MacroTextureNameID;
+};
+
+// lights that were used to illuminate the world
+enum emittype_t
+{
+ emit_surface, // 90 degree spotlight
+ emit_point, // simple point light source
+ emit_spotlight, // spotlight with penumbra
+ emit_skylight, // directional light with no falloff (surface must trace to SKY texture)
+ emit_quakelight, // linear falloff, non-lambertian
+ emit_skyambient, // spherical light source with no falloff (surface must trace to SKY texture)
+};
+
+
+// Flags for dworldlight_t::flags
+#define DWL_FLAGS_INAMBIENTCUBE 0x0001 // This says that the light was put into the per-leaf ambient cubes.
+
+
+struct dworldlight_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ Vector origin;
+ Vector intensity;
+ Vector normal; // for surfaces and spotlights
+ int cluster;
+ emittype_t type;
+ int style;
+ float stopdot; // start of penumbra for emit_spotlight
+ float stopdot2; // end of penumbra for emit_spotlight
+ float exponent; //
+ float radius; // cutoff distance
+ // falloff for emit_spotlight + emit_point:
+ // 1 / (constant_attn + linear_attn * dist + quadratic_attn * dist^2)
+ float constant_attn;
+ float linear_attn;
+ float quadratic_attn;
+ int flags; // Uses a combination of the DWL_FLAGS_ defines.
+ int texinfo; //
+ int owner; // entity that this light it relative to
+};
+
+struct dcubemapsample_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int origin[3]; // position of light snapped to the nearest integer
+ // the filename for the vtf file is derived from the position
+ unsigned char size; // 0 - default
+ // otherwise, 1<<(size-1)
+};
+
+#define OVERLAY_BSP_FACE_COUNT 64
+
+#define OVERLAY_NUM_RENDER_ORDERS (1<<OVERLAY_RENDER_ORDER_NUM_BITS)
+#define OVERLAY_RENDER_ORDER_NUM_BITS 2
+#define OVERLAY_RENDER_ORDER_MASK 0xC000 // top 2 bits set
+
+struct doverlay_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int nId;
+ short nTexInfo;
+
+ // Accessors..
+ void SetFaceCount( unsigned short count );
+ unsigned short GetFaceCount() const;
+
+ void SetRenderOrder( unsigned short order );
+ unsigned short GetRenderOrder() const;
+
+private:
+ unsigned short m_nFaceCountAndRenderOrder;
+
+public:
+ int aFaces[OVERLAY_BSP_FACE_COUNT];
+ float flU[2];
+ float flV[2];
+ Vector vecUVPoints[4];
+ Vector vecOrigin;
+ Vector vecBasisNormal;
+};
+
+
+inline void doverlay_t::SetFaceCount( unsigned short count )
+{
+ m_nFaceCountAndRenderOrder &= OVERLAY_RENDER_ORDER_MASK;
+ m_nFaceCountAndRenderOrder |= (count & ~OVERLAY_RENDER_ORDER_MASK);
+}
+
+inline unsigned short doverlay_t::GetFaceCount() const
+{
+ return m_nFaceCountAndRenderOrder & ~OVERLAY_RENDER_ORDER_MASK;
+}
+
+inline void doverlay_t::SetRenderOrder( unsigned short order )
+{
+ m_nFaceCountAndRenderOrder &= ~OVERLAY_RENDER_ORDER_MASK;
+ m_nFaceCountAndRenderOrder |= (order << (16 - OVERLAY_RENDER_ORDER_NUM_BITS)); // leave 2 bits for render order.
+}
+
+inline unsigned short doverlay_t::GetRenderOrder() const
+{
+ return (m_nFaceCountAndRenderOrder >> (16 - OVERLAY_RENDER_ORDER_NUM_BITS));
+}
+
+
+struct doverlayfade_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+
+ float flFadeDistMinSq;
+ float flFadeDistMaxSq;
+};
+
+
+#define WATEROVERLAY_BSP_FACE_COUNT 256
+#define WATEROVERLAY_RENDER_ORDER_NUM_BITS 2
+#define WATEROVERLAY_NUM_RENDER_ORDERS (1<<WATEROVERLAY_RENDER_ORDER_NUM_BITS)
+#define WATEROVERLAY_RENDER_ORDER_MASK 0xC000 // top 2 bits set
+struct dwateroverlay_t
+{
+ DECLARE_BYTESWAP_DATADESC();
+ int nId;
+ short nTexInfo;
+
+ // Accessors..
+ void SetFaceCount( unsigned short count );
+ unsigned short GetFaceCount() const;
+ void SetRenderOrder( unsigned short order );
+ unsigned short GetRenderOrder() const;
+
+private:
+
+ unsigned short m_nFaceCountAndRenderOrder;
+
+public:
+
+ int aFaces[WATEROVERLAY_BSP_FACE_COUNT];
+ float flU[2];
+ float flV[2];
+ Vector vecUVPoints[4];
+ Vector vecOrigin;
+ Vector vecBasisNormal;
+};
+
+inline void dwateroverlay_t::SetFaceCount( unsigned short count )
+{
+ m_nFaceCountAndRenderOrder &= WATEROVERLAY_RENDER_ORDER_MASK;
+ m_nFaceCountAndRenderOrder |= (count & ~WATEROVERLAY_RENDER_ORDER_MASK);
+}
+
+inline unsigned short dwateroverlay_t::GetFaceCount() const
+{
+ return m_nFaceCountAndRenderOrder & ~WATEROVERLAY_RENDER_ORDER_MASK;
+}
+
+inline void dwateroverlay_t::SetRenderOrder( unsigned short order )
+{
+ m_nFaceCountAndRenderOrder &= ~WATEROVERLAY_RENDER_ORDER_MASK;
+ m_nFaceCountAndRenderOrder |= ( order << ( 16 - WATEROVERLAY_RENDER_ORDER_NUM_BITS ) ); // leave 2 bits for render order.
+}
+
+inline unsigned short dwateroverlay_t::GetRenderOrder() const
+{
+ return ( m_nFaceCountAndRenderOrder >> ( 16 - WATEROVERLAY_RENDER_ORDER_NUM_BITS ) );
+}
+
+#ifndef _DEF_BYTE_
+#define _DEF_BYTE_
+typedef unsigned char byte;
+typedef unsigned short word;
+#endif
+
+
+#define ANGLE_UP -1
+#define ANGLE_DOWN -2
+
+
+//===============
+
+
+struct epair_t
+{
+ epair_t *next;
+ char *key;
+ char *value;
+};
+
+// finalized page of surface's lightmaps
+#define MAX_LIGHTMAPPAGE_WIDTH 256
+#define MAX_LIGHTMAPPAGE_HEIGHT 128
+typedef struct nameForDatadesc_dlightmappage_t // unnamed structs collide in the datadesc macros
+{
+ DECLARE_BYTESWAP_DATADESC();
+ byte data[MAX_LIGHTMAPPAGE_WIDTH*MAX_LIGHTMAPPAGE_HEIGHT];
+ byte palette[256*4];
+} dlightmappage_t;
+
+typedef struct nameForDatadesc_dlightmappageinfo_t // unnamed structs collide in the datadesc macros
+{
+ DECLARE_BYTESWAP_DATADESC();
+ byte page; // lightmap page [0..?]
+ byte offset[2]; // offset into page (s,t)
+ byte pad; // unused
+ ColorRGBExp32 avgColor; // average used for runtime lighting calcs
+} dlightmappageinfo_t;
+
+#endif // BSPFILE_H