//========= 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< 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; // 360 only: 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 #ifdef _WIN32 #pragma warning( disable:4201 ) // C4201: nonstandard extension used: nameless struct/union #endif 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; }; #ifdef _WIN32 #pragma warning( default:4201 ) // C4201: nonstandard extension used: nameless struct/union #endif #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<> (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<> ( 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