1
0
Fork 0
mirror of https://codeberg.org/icewind/vbsp.git synced 2026-06-03 10:44:07 +02:00

texture info handling

This commit is contained in:
Robin Appelman 2022-12-07 22:03:32 +01:00
commit e132a34a00
6 changed files with 69 additions and 7 deletions

View file

@ -1,3 +1,4 @@
#[allow(unused_imports)]
use std::ops::Deref;
fn main() -> Result<(), vbsp::BspError> {
@ -12,9 +13,13 @@ fn main() -> Result<(), vbsp::BspError> {
// }
// }
for prop in bsp.static_props() {
dbg!(prop.deref());
dbg!(prop.model());
// for prop in bsp.static_props() {
// dbg!(prop.deref());
// dbg!(prop.model());
// }
for tex in bsp.textures() {
println!("{}", tex.name());
}
Ok(())

View file

@ -43,10 +43,10 @@ impl<'a> BspFile<'a> {
pub fn lump_reader(&self, lump: LumpType) -> BspResult<LumpReader<Cursor<Cow<[u8]>>>> {
let data = self.get_lump(lump)?;
Ok(LumpReader::new(data))
Ok(LumpReader::new(data, lump))
}
fn get_lump(&self, lump: LumpType) -> BspResult<Cow<[u8]>> {
pub fn get_lump(&self, lump: LumpType) -> BspResult<Cow<[u8]>> {
let lump = &self.directories[lump];
let raw_data = self
.data

View file

@ -2,6 +2,7 @@ use crate::data::*;
use std::num::{ParseFloatError, ParseIntError};
use thiserror::Error;
use zip::result::ZipError;
use crate::bspfile::LumpType;
#[non_exhaustive]
#[derive(Debug, Error)]
@ -16,6 +17,7 @@ pub enum BspError {
MalformedCompressedGameLump,
#[error("Invalid lump size, lump size {lump_size} is not a multiple of the element size {element_size}")]
InvalidLumpSize {
lump: LumpType,
element_size: usize,
lump_size: usize,
},

View file

@ -119,3 +119,24 @@ impl<'a> Handle<'a, Leaf> {
.filter_map(move |leaf_face| bsp.face(leaf_face.face as usize))
}
}
impl<'a> Handle<'a, TextureInfo> {
pub fn texture_data(&self) -> Handle<'a, TextureData> {
Handle::new(self.bsp, &self.bsp.textures_data[self.data.texture_data_index as usize])
}
pub fn name(&self) -> &'a str {
self.texture_data().name()
}
}
impl<'a> Handle<'a, TextureData> {
pub fn name(&self) -> &'a str {
let start = self.bsp.texture_string_tables[self.name_string_table_id as usize] as usize;
let part = &self.bsp.texture_string_data[start..];
if let Some((s, _)) = part.split_once("\0") {
s
} else {
part
}
}
}

View file

@ -159,6 +159,8 @@ pub struct Bsp {
pub entities: Entities,
pub textures_data: Vec<TextureData>,
pub textures_info: Vec<TextureInfo>,
pub texture_string_tables: Vec<i32>,
pub texture_string_data: String,
pub planes: Vec<Plane>,
pub nodes: Vec<Node>,
pub leaves: Leaves,
@ -191,6 +193,12 @@ impl Bsp {
let textures_info = bsp_file
.lump_reader(LumpType::TextureInfo)?
.read_vec(|r| r.read())?;
let texture_string_tables = bsp_file
.lump_reader(LumpType::TextureDataStringTable)?
.read_vec(|r| r.read())?;
let texture_string_data = String::from_utf8(bsp_file
.get_lump(LumpType::TextureDataStringData)?
.into_owned()).map_err(|e| BspError::String(StringError::NonUTF8(e.utf8_error())))?;
let planes = bsp_file
.lump_reader(LumpType::Planes)?
.read_vec(|r| r.read())?;
@ -253,6 +261,8 @@ impl Bsp {
entities,
textures_data,
textures_info,
texture_string_tables,
texture_string_data,
planes,
nodes,
leaves,
@ -315,6 +325,11 @@ impl Bsp {
self.models.iter().map(move |m| Handle::new(self, m))
}
/// Get all models stored in the bsp
pub fn textures(&self) -> impl Iterator<Item = Handle<'_, TextureInfo>> {
self.textures_info.iter().map(move |m| Handle::new(self, m))
}
/// Find a leaf for a specific position
pub fn leaf_at(&self, point: Vector) -> Handle<'_, Leaf> {
let mut current = self.root_node();
@ -424,6 +439,22 @@ impl Bsp {
"texture_info",
"texture_data",
)?;
self.validate_indexes(
self.textures_data
.iter()
.map(|texture| texture.name_string_table_id),
&self.texture_string_tables,
"textures_data",
"texture_string_tables",
)?;
self.validate_indexes(
self.texture_string_tables
.iter()
.map(|texture| *texture),
&self.texture_string_data.as_bytes(),
"texture_string_tables",
"texture_string_data",
)?;
self.validate_indexes(
self.nodes.iter().map(|node| node.plane_index),
&self.planes,

View file

@ -1,6 +1,5 @@
use crate::*;
use binrw::BinReaderExt;
// use std::any::type_name;
use std::borrow::Cow;
use std::fmt::Debug;
use std::mem::size_of;
@ -8,15 +7,17 @@ use std::mem::size_of;
pub struct LumpReader<R> {
inner: R,
length: usize,
lump: LumpType,
}
impl<'a> LumpReader<Cursor<Cow<'a, [u8]>>> {
pub fn new(data: Cow<'a, [u8]>) -> Self {
pub fn new(data: Cow<'a, [u8]>, lump: LumpType) -> Self {
let length = data.len();
let reader = Cursor::new(data);
LumpReader {
inner: reader,
length,
lump,
}
}
@ -32,12 +33,14 @@ impl<R: BinReaderExt + Read> LumpReader<R> {
Ok(Entities { entities })
}
/// Read a list of items with a fixed size
pub fn read_vec<F, T>(&mut self, mut f: F) -> BspResult<Vec<T>>
where
F: FnMut(&mut LumpReader<R>) -> BspResult<T>,
{
if self.length % size_of::<T>() != 0 {
return Err(BspError::InvalidLumpSize {
lump: self.lump,
element_size: size_of::<T>(),
lump_size: self.length,
});