diff --git a/Cargo.lock b/Cargo.lock index aa98a27..c87e690 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,6 +142,17 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +[[package]] +name = "binrw" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173901312e9850391d4d7c1318c4e099fdc037d61870fca427429830efdb4e5f" +dependencies = [ + "array-init", + "binrw_derive 0.13.3", + "bytemuck", +] + [[package]] name = "binrw" version = "0.14.1" @@ -149,10 +160,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d4bca59c20d6f40c2cc0802afbe1e788b89096f61bdf7aeea6bf00f10c2909b" dependencies = [ "array-init", - "binrw_derive", + "binrw_derive 0.14.1", "bytemuck", ] +[[package]] +name = "binrw_derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb515fdd6f8d3a357c8e19b8ec59ef53880807864329b1cb1cba5c53bf76557e" +dependencies = [ + "either", + "owo-colors", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "binrw_derive" version = "0.14.1" @@ -1959,7 +1983,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36372fd7feb6d3c5780d2ada39d1397be9e196ddfbb23ba1d84e7a75cf790adb" dependencies = [ - "binrw", + "binrw 0.14.1", "lazy-regex", ] @@ -2332,6 +2356,7 @@ dependencies = [ "strafesnet_deferred_loader", "vbsp", "vmdl", + "vpk", ] [[package]] @@ -2422,7 +2447,7 @@ dependencies = [ name = "strafesnet_snf" version = "0.2.0" dependencies = [ - "binrw", + "binrw 0.14.1", "id", "strafesnet_common", ] @@ -2704,7 +2729,7 @@ checksum = "f14a5685e0bb386aac9b9c6046a05152a46a0bc58d53afb3fbe577f1a1c2bb05" dependencies = [ "ahash", "arrayvec", - "binrw", + "binrw 0.14.1", "bitflags 2.8.0", "bv", "cgmath", @@ -2755,6 +2780,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "vpk" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60ec10e731515f58d5494d472f027d9c6fc8500fcb790ff55751031bcad87b6b" +dependencies = [ + "ahash", + "binrw 0.13.3", + "thiserror 1.0.69", +] + [[package]] name = "walkdir" version = "2.5.0" diff --git a/lib/bsp_loader/Cargo.toml b/lib/bsp_loader/Cargo.toml index 971cc20..60b3dfe 100644 --- a/lib/bsp_loader/Cargo.toml +++ b/lib/bsp_loader/Cargo.toml @@ -15,3 +15,4 @@ strafesnet_common = { path = "../common", registry = "strafesnet" } strafesnet_deferred_loader = { path = "../deferred_loader" } vbsp = "0.6.0" vmdl = "0.2.0" +vpk = "0.2.0" diff --git a/lib/bsp_loader/src/lib.rs b/lib/bsp_loader/src/lib.rs index c4e9f19..d160417 100644 --- a/lib/bsp_loader/src/lib.rs +++ b/lib/bsp_loader/src/lib.rs @@ -62,7 +62,7 @@ impl Bsp{ pub const fn new(value:vbsp::Bsp)->Self{ Self(value) } - pub fn to_snf(&self,failure_mode:LoadFailureMode)->Result<strafesnet_common::map::CompleteMap,LoadError>{ + pub fn to_snf(&self,failure_mode:LoadFailureMode,vpk_list:&[vpk::VPK])->Result<strafesnet_common::map::CompleteMap,LoadError>{ let mut texture_deferred_loader=RenderConfigDeferredLoader::new(); let mut mesh_deferred_loader=MeshDeferredLoader::new(); @@ -72,7 +72,7 @@ impl Bsp{ &mut mesh_deferred_loader, ); - let mut mesh_loader=loader::MeshLoader::new(self,&mut texture_deferred_loader); + let mut mesh_loader=loader::MeshLoader::new(self,vpk_list,&mut texture_deferred_loader); let prop_meshes=mesh_deferred_loader.into_meshes(&mut mesh_loader,failure_mode).map_err(LoadError::Mesh)?; let map_step2=map_step1.add_prop_meshes(prop_meshes); diff --git a/lib/bsp_loader/src/loader.rs b/lib/bsp_loader/src/loader.rs index bda2f29..dab5cbf 100644 --- a/lib/bsp_loader/src/loader.rs +++ b/lib/bsp_loader/src/loader.rs @@ -72,22 +72,40 @@ impl From<vbsp::BspError> for MeshError{ } } -pub struct MeshLoader<'a,'b>{ +pub struct MeshLoader<'a,'b,'c>{ bsp:&'a Bsp, + vpks:&'c [vpk::VPK], deferred_loader:&'b mut strafesnet_deferred_loader::deferred_loader::RenderConfigDeferredLoader<Cow<'a,str>>, } -impl MeshLoader<'_,'_>{ - pub fn new<'a,'b>( +impl MeshLoader<'_,'_,'_>{ + pub fn new<'a,'b,'c>( bsp:&'a Bsp, + vpks:&'c [vpk::VPK], deferred_loader:&'b mut strafesnet_deferred_loader::deferred_loader::RenderConfigDeferredLoader<Cow<'a,str>>, - )->MeshLoader<'a,'b>{ + )->MeshLoader<'a,'b,'c>{ MeshLoader{ bsp, + vpks, deferred_loader, } } + fn find(&self,path:&str)->Result<Option<Cow<[u8]>>,vbsp::BspError>{ + // search bsp + if let Some(data)=self.bsp.as_ref().pack.get(path)?{ + return Ok(Some(Cow::Owned(data))); + } + + //search each vpk + for vpk in self.vpks{ + if let Some(vpk_entry)=vpk.tree.get(path){ + return Ok(Some(vpk_entry.get()?)); + } + } + + Ok(None) + } } -impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_>{ +impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_,'_>{ type Error=MeshError; type Index=&'a str; fn load(&mut self,index:Self::Index)->Result<vmdl::Model,Self::Error>{ @@ -99,10 +117,9 @@ impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_>{ vvd_path.set_extension("vvd"); vtx_path.set_extension("dx90.vtx"); // TODO: search more packs, possibly using an index of multiple packs - let bsp=self.bsp.as_ref(); - let mdl=bsp.pack.get(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?; - let vtx=bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?; - let vvd=bsp.pack.get(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?; + let mdl=self.find(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?; + let vtx=self.find(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?; + let vvd=self.find(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?; Ok(vmdl::Model::from_parts( vmdl::mdl::Mdl::read(mdl.as_ref())?, vmdl::vtx::Vtx::read(vtx.as_ref())?, @@ -111,7 +128,7 @@ impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_>{ } } -impl<'a> Loader<Mesh> for MeshLoader<'a,'_>{ +impl<'a> Loader<Mesh> for MeshLoader<'a,'_,'_>{ type Error=MeshError; type Index=&'a str; fn load(&mut self,index:Self::Index)->Result<Mesh,Self::Error>{ diff --git a/strafe-client/src/file.rs b/strafe-client/src/file.rs index 6fb2bd6..d27d70a 100644 --- a/strafe-client/src/file.rs +++ b/strafe-client/src/file.rs @@ -105,7 +105,7 @@ pub fn load<P:AsRef<std::path::Path>>(path:P)->Result<LoadFormat,LoadError>{ }, #[cfg(feature="source")] ReadFormat::Source(bsp)=>Ok(LoadFormat::Map( - bsp.to_snf(LoadFailureMode::DefaultToNone).map_err(LoadError::LoadSource)? + bsp.to_snf(LoadFailureMode::DefaultToNone,&[]).map_err(LoadError::LoadSource)? )), } }