Skip to content

Commit

Permalink
new deku (#747)
Browse files Browse the repository at this point in the history
* Update to deku v0.18.0

* rust: Fix bit-endianness issue with new-deku

This was the cause of all of our WoW rendering failures with new-deku. Unfortunate we can't (yet?) use Deku for this part, but honestly I think the shift + mask is better than a loop anyway.

* rust: Map seek errors to deku errors

* rust: Fix Unity loading

The deku::byte_offset trick we do for alignment requires reader.bits_read to be correct, as that's the number we pad by. In our PackedVec implementations, we read a u8, and then later skip over it, which double-counts from the perspective of reader.bits_read. Fix this by adjusting after we read it.

* rust: Use std::io instead of deku::no_std_io

* rust: Update polymorph
  • Loading branch information
magcius authored Jan 24, 2025
1 parent 4ed13d8 commit b5b857d
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 337 deletions.
90 changes: 68 additions & 22 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ opt-level = "s"
[dependencies]
byteorder = "1.4.3"
console_error_panic_hook = "0.1.7"
deku = { version = "0.16.0", features = ["logging"] }
deku = { version = "0.18.1", features = ["logging"] }
env_logger = "0.10.1"
inflate = "0.4.5"
js-sys = "0.3.60"
Expand Down
15 changes: 9 additions & 6 deletions rust/src/unity/asset_file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use deku::bitvec::BitSlice;
use deku::{DekuContainerRead, DekuRead};
use std::io::Cursor;

use deku::reader::Reader;
use deku::{DekuContainerRead, DekuReader};
use wasm_bindgen::prelude::*;

use crate::unity::types::wasm::WasmFriendlyPPtr;
Expand Down Expand Up @@ -39,11 +41,12 @@ impl AssetFile {

pub fn append_metadata_chunk(&mut self, data: &[u8]) -> Result<(), String> {
// data will be the file from bytes 0..data_offset, so skip to where the metadata starts
let bitslice = BitSlice::from_slice(data);
let (rest, _) = SerializedFileHeader::read(&bitslice, ())
let mut cursor = Cursor::new(data);
let mut reader = Reader::new(&mut cursor);
let _header = SerializedFileHeader::from_reader_with_ctx(&mut reader, ())
.map_err(|err| format!("failed to parse metadata file header: {:?}", err))?;
match SerializedFileMetadata::read(rest, self.header.version) {
Ok((_, metadata)) => self.metadata = Some(metadata),
match SerializedFileMetadata::from_reader_with_ctx(&mut reader, self.header.version) {
Ok(metadata) => self.metadata = Some(metadata),
Err(err) => return Err(format!("failed to parse metadata: {:?}", err)),
}
Ok(())
Expand Down
36 changes: 14 additions & 22 deletions rust/src/unity/types/binary.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

use deku::prelude::*;

// https://github.com/AssetRipper/TypeTreeDumps/blob/main/StructsDump/release/2019.4.39f1.dump
Expand Down Expand Up @@ -153,14 +154,14 @@ pub struct Mesh {
}

#[derive(DekuRead, Clone, Copy, Debug)]
#[deku(type = "i32")]
#[deku(id_type = "i32")]
pub enum IndexFormat {
UInt16 = 0,
UInt32 = 1,
}

#[derive(DekuRead, Clone, Copy, Debug)]
#[deku(type = "u8")]
#[deku(id_type = "u8")]
pub enum MeshCompression {
Off = 0,
Low = 1,
Expand Down Expand Up @@ -220,21 +221,12 @@ pub struct ByteArray {
pub data: Vec<u8>,
}

impl<'a> DekuRead<'a> for ByteArray {
fn read(
input: &'a deku::bitvec::BitSlice<u8, deku::bitvec::Msb0>,
ctx: (),
) -> Result<(&'a deku::bitvec::BitSlice<u8, deku::bitvec::Msb0>, Self), DekuError>
where Self: Sized {
let (rest, count) = i32::read(input, ctx)?;
let (data_bits, rest) = rest.split_at(count as usize * 8);
let bytes = data_bits.domain().region().unwrap().1;
Ok((
rest,
Self {
data: bytes.to_vec(),
},
))
impl<'a, Ctx> DekuReader<'a, Ctx> for ByteArray where Ctx: Copy {
fn from_reader_with_ctx<R: std::io::Read + std::io::Seek>(reader: &mut Reader<R>, _ctx: Ctx) -> Result<Self, DekuError> {
let count = i32::from_reader_with_ctx(reader, ())? as usize;
let mut buf = vec![0x00; count];
reader.read_bytes(count, &mut buf)?;
Ok(ByteArray{ data: buf })
}
}

Expand Down Expand Up @@ -271,7 +263,7 @@ pub struct ChannelInfo {
}

#[derive(DekuRead, Clone, Debug)]
#[deku(type = "u8")]
#[deku(id_type = "u8")]
pub enum VertexFormat {
#[deku(id = "0")] Float,
#[deku(id = "1")] Float16,
Expand Down Expand Up @@ -390,15 +382,15 @@ pub struct GLTextureSettings {
}

#[derive(DekuRead, Clone, Debug)]
#[deku(type = "i32")]
#[deku(id_type = "i32")]
pub enum TextureFilterMode {
Nearest = 0,
Bilinear = 1,
Trilinear = 2,
}

#[derive(DekuRead, Clone, Debug)]
#[deku(type = "i32")]
#[deku(id_type = "i32")]
pub enum TextureWrapMode {
Repeat = 0,
Clamp = 1,
Expand All @@ -408,7 +400,7 @@ pub enum TextureWrapMode {

// copied from https://github.com/Unity-Technologies/UnityCsReference/blob/129a67089d125df5b95b659d3535deaf9968e86c/Editor/Mono/AssetPipeline/TextureImporterEnums.cs#L37
#[derive(DekuRead, Clone, Debug)]
#[deku(type = "i32")]
#[deku(id_type = "i32")]
pub enum TextureFormat {
// Alpha 8 bit texture format.
Alpha8 = 1,
Expand Down Expand Up @@ -523,7 +515,7 @@ pub enum TextureFormat {
}

#[derive(DekuRead, Clone, Debug)]
#[deku(type = "i32")]
#[deku(id_type = "i32")]
pub enum ColorSpace {
Linear = 0x00,
SRGB = 0x01,
Expand Down
2 changes: 1 addition & 1 deletion rust/src/unity/types/class_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use deku::prelude::*;

#[wasm_bindgen(js_name = "UnityClassID")]
#[derive(DekuRead, Debug, Copy, Clone, PartialEq)]
#[deku(type = "i32")]
#[deku(id_type = "i32")]
#[repr(i32)]
pub enum ClassID {
#[deku(id = "-1")] UnknownType,
Expand Down
Loading

0 comments on commit b5b857d

Please sign in to comment.