You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1156 lines
32 KiB
1156 lines
32 KiB
//========= 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
|
|
|