1
0
Fork 0
mirror of https://codeberg.org/icewind/vbsp.git synced 2026-06-03 18:54:05 +02:00

add pakfile support

This commit is contained in:
Robin Appelman 2022-03-20 15:31:40 +01:00
commit dbce06b508
5 changed files with 70 additions and 1 deletions

View file

@ -21,6 +21,7 @@ static_assertions = "1.1.0"
num_enum = "0.5.6" num_enum = "0.5.6"
vbsp-derive = { path = "derive", version = "*" } vbsp-derive = { path = "derive", version = "*" }
cgmath = "0.18.0" cgmath = "0.18.0"
zip = { version = "0.5.13", path = "../zip", default-features = false, features = ["lzma"] }
[dev-dependencies] [dev-dependencies]
obj = "0.10" obj = "0.10"

View file

@ -8,16 +8,21 @@ pub use self::entity::*;
pub use self::game::*; pub use self::game::*;
pub use self::vector::*; pub use self::vector::*;
use crate::bspfile::LumpType; use crate::bspfile::LumpType;
use crate::StringError; use crate::{BspResult, StringError};
use arrayvec::ArrayString; use arrayvec::ArrayString;
use binrw::io::SeekFrom; use binrw::io::SeekFrom;
use binrw::{BinRead, BinResult, ReadOptions}; use binrw::{BinRead, BinResult, ReadOptions};
use bitflags::bitflags; use bitflags::bitflags;
use bv::BitVec; use bv::BitVec;
use std::borrow::Cow;
use std::fmt; use std::fmt;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::io::{Cursor, Read};
use std::mem::{align_of, size_of}; use std::mem::{align_of, size_of};
use std::ops::Index; use std::ops::Index;
use std::sync::Mutex;
use zip::result::ZipError;
use zip::ZipArchive;
#[cfg(test)] #[cfg(test)]
fn test_read_bytes<T: BinRead>() fn test_read_bytes<T: BinRead>()
@ -410,3 +415,56 @@ impl VisData {
visible_clusters visible_clusters
} }
} }
pub struct Packfile {
zip: Mutex<ZipArchive<Cursor<Vec<u8>>>>,
}
impl Clone for Packfile {
fn clone(&self) -> Self {
Packfile {
zip: Mutex::new(self.zip.lock().unwrap().clone()),
}
}
}
impl Debug for Packfile {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Packfile")
.field(
"zip",
&self
.zip
.lock()
.unwrap()
.file_names()
.collect::<Vec<_>>()
.join(", "),
)
.finish()
}
}
impl Packfile {
pub fn read(data: Cow<[u8]>) -> BspResult<Self> {
let reader = Cursor::new(data.into_owned());
let zip = Mutex::new(ZipArchive::new(reader)?);
Ok(Packfile { zip })
}
pub fn get(&self, name: &str) -> BspResult<Option<Vec<u8>>> {
let mut zip = self.zip.lock().unwrap();
let mut entry = match zip.by_name(name) {
Ok(entry) => entry,
Err(ZipError::FileNotFound) => {
return Ok(None);
}
Err(e) => {
return Err(e.into());
}
};
let mut buff = vec![0; entry.size() as usize];
entry.read_exact(&mut buff)?;
Ok(Some(buff))
}
}

View file

@ -1,6 +1,7 @@
use crate::data::*; use crate::data::*;
use std::num::{ParseFloatError, ParseIntError}; use std::num::{ParseFloatError, ParseIntError};
use thiserror::Error; use thiserror::Error;
use zip::result::ZipError;
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -34,6 +35,8 @@ pub enum BspError {
Validation(#[from] ValidationError), Validation(#[from] ValidationError),
#[error(transparent)] #[error(transparent)]
LumpVersion(UnsupportedLumpVersion), LumpVersion(UnsupportedLumpVersion),
#[error(transparent)]
Zip(#[from] ZipError),
} }
impl From<binrw::Error> for BspError { impl From<binrw::Error> for BspError {

View file

@ -177,6 +177,7 @@ pub struct Bsp {
pub displacement_vertices: Vec<DisplacementVertex>, pub displacement_vertices: Vec<DisplacementVertex>,
pub displacement_triangles: Vec<DisplacementTriangle>, pub displacement_triangles: Vec<DisplacementTriangle>,
pub static_props: PropStaticGameLump, pub static_props: PropStaticGameLump,
pub pack: Packfile,
} }
impl Bsp { impl Bsp {
@ -241,6 +242,7 @@ impl Bsp {
.lump_reader(LumpType::DisplacementTris)? .lump_reader(LumpType::DisplacementTris)?
.read_vec(|r| r.read())?; .read_vec(|r| r.read())?;
let game_lumps: GameLumpHeader = bsp_file.lump_reader(LumpType::GameLump)?.read()?; let game_lumps: GameLumpHeader = bsp_file.lump_reader(LumpType::GameLump)?.read()?;
let pack = Packfile::read(bsp_file.lump_reader(LumpType::PakFile)?.into_data())?;
let static_props = game_lumps let static_props = game_lumps
.find(data) .find(data)
@ -269,6 +271,7 @@ impl Bsp {
displacement_vertices, displacement_vertices,
displacement_triangles, displacement_triangles,
static_props, static_props,
pack,
}; };
bsp.validate()?; bsp.validate()?;
Ok(bsp) Ok(bsp)

View file

@ -19,6 +19,10 @@ impl<'a> LumpReader<Cursor<Cow<'a, [u8]>>> {
length, length,
} }
} }
pub fn into_data(self) -> Cow<'a, [u8]> {
self.inner.into_inner()
}
} }
impl<R: BinReaderExt + Read> LumpReader<R> { impl<R: BinReaderExt + Read> LumpReader<R> {