1#[macro_use]
19extern crate bitflags;
20extern crate bit_vec;
21extern crate nalgebra as na;
22
23#[macro_use]
24mod macros;
25pub mod directory;
26pub mod lumps;
27pub mod types;
28
29use lumps::*;
30use directory::Header;
31use types::{Error, Result};
32
33#[derive(Debug, Clone)]
35pub struct BSPFile {
36 pub directory: Header,
37 pub entities: EntitiesLump,
38 pub textures: TexturesLump,
39 pub planes: PlanesLump,
40 pub light_vols: LightVolsLump,
41 pub brushes: BrushesLump,
42 pub vertices: VerticesLump,
43 pub meshverts: MeshVertsLump,
44 pub light_maps: LightMapsLump,
45 pub effects: EffectsLump,
46 pub faces: FaceLump,
47 pub tree: BSPTree,
48 pub visdata: VisDataLump,
49 pub models: ModelsLump,
50
51 pub advertisements: Option<AdvertisementsLump>
53}
54
55impl BSPFile {
56 pub fn from_buffer(buf: Box<[u8]>) -> Result<BSPFile> {
58 let header = Header::from(&buf)?;
59
60 match header.version {
61 0x2e | 0x2f => {
63 let entities = EntitiesLump::from_lump(header.get_lump(&buf, 0))?;
64 let textures = TexturesLump::from_lump(header.get_lump(&buf, 1))?;
65 let planes = PlanesLump::from_lump(header.get_lump(&buf, 2))?;
66 let vertices = VerticesLump::from_lump(header.get_lump(&buf, 10))?;
67 let meshverts = MeshVertsLump::from_lump(header.get_lump(&buf, 11))?;
68 let light_maps = LightMapsLump::from_lump(header.get_lump(&buf, 14))?;
69 let light_vols = LightVolsLump::from_lump(header.get_lump(&buf, 15))?;
70 let visdata = VisDataLump::from_lump(header.get_lump(&buf, 16))?;
71 let brushes = BrushesLump::from_lump(
72 header.get_lump(&buf, 8),
73 header.get_lump(&buf, 9),
74 &textures,
75 &planes
76 )?;
77 let effects = EffectsLump::from_lump(header.get_lump(&buf, 12), &brushes)?;
78 let faces = FaceLump::from_lump(
79 header.get_lump(&buf, 13),
80 &textures,
81 &effects,
82 &vertices,
83 &meshverts,
84 &light_maps,
85 )?;
86 let tree = BSPTree::from_lumps(
87 header.get_lump(&buf, 3),
88 header.get_lump(&buf, 4),
89 header.get_lump(&buf, 5),
90 header.get_lump(&buf, 6),
91 &faces,
92 &brushes,
93 )?;
94
95 let models = ModelsLump::from_lump(header.get_lump(&buf, 7), &faces, &brushes)?;
96
97 let advertisements = if header.version == 0x2f {
99 Some(AdvertisementsLump::from_lump(header.get_lump(&buf, 17))?)
100 } else {
101 None
102 };
103
104 Ok(BSPFile {
105 directory: header,
106 entities,
107 textures,
108 planes,
109 light_vols,
110 light_maps,
111 vertices,
112 meshverts,
113 visdata,
114 advertisements,
115 brushes,
116 effects,
117 faces,
118 tree,
119 models
120 })
121 }
122 _ => Err(Error::Unsupported {
123 version: header.version,
124 }),
125 }
126 }
127}