use only 1 pixel type, add testing for world and fix some logic errors

This commit is contained in:
bgkillas 2025-08-29 18:42:43 -04:00
parent 2d617b900d
commit 19315ef268
17 changed files with 408 additions and 582 deletions

100
blob_guy/Cargo.lock generated
View file

@ -236,9 +236,9 @@ dependencies = [
[[package]]
name = "async-executor"
version = "1.13.2"
version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa"
checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8"
dependencies = [
"async-task",
"concurrent-queue",
@ -1164,12 +1164,12 @@ dependencies = [
[[package]]
name = "gethostname"
version = "0.4.3"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55"
dependencies = [
"libc",
"windows-targets 0.48.5",
"rustix 1.0.8",
"windows-targets 0.52.6",
]
[[package]]
@ -2328,9 +2328,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
name = "potential_utf"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
dependencies = [
"zerovec",
]
@ -2458,7 +2458,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "rupl"
version = "0.1.2"
source = "git+https://github.com/bgkillas/rupl.git#20e9893cdab4461afb40f23386e114959739fca3"
source = "git+https://github.com/bgkillas/rupl.git#c5fdcfca4a47ac65300b1a2d3706e95a0f31f149"
dependencies = [
"egui",
]
@ -3030,11 +3030,11 @@ dependencies = [
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
version = "0.14.3+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
dependencies = [
"wit-bindgen-rt",
"wit-bindgen",
]
[[package]]
@ -3654,21 +3654,6 @@ dependencies = [
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
@ -3717,12 +3702,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
@ -3741,12 +3720,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
@ -3765,12 +3738,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@ -3801,12 +3768,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
@ -3825,12 +3786,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
@ -3849,12 +3804,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
@ -3873,12 +3822,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
@ -3953,13 +3896,10 @@ dependencies = [
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
name = "wit-bindgen"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.3",
]
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
[[package]]
name = "writeable"
@ -3980,24 +3920,24 @@ dependencies = [
[[package]]
name = "x11rb"
version = "0.13.1"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
dependencies = [
"as-raw-xcb-connection",
"gethostname",
"libc",
"libloading",
"once_cell",
"rustix 0.38.44",
"rustix 1.0.8",
"x11rb-protocol",
]
[[package]]
name = "x11rb-protocol"
version = "0.13.1"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
[[package]]
name = "xcursor"

View file

@ -21,8 +21,8 @@ noita_api = {path = "../noita_api"}
eyre = "0.6.12"
smallvec = "1.15.1"
rustc-hash = "2.1.1"
rayon = "1.10.0"
rayon = "1.11.0"
[dev-dependencies]
rupl = {git = "https://github.com/bgkillas/rupl.git", default-features = false, features = ["egui"] }
eframe = "0.32.0"
eframe = "0.32.1"

21
ewext/Cargo.lock generated
View file

@ -50,12 +50,6 @@ dependencies = [
"syn",
]
[[package]]
name = "bitflags"
version = "2.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d"
[[package]]
name = "bytemuck"
version = "1.23.2"
@ -502,11 +496,11 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
version = "0.14.3+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
dependencies = [
"wit-bindgen-rt",
"wit-bindgen",
]
[[package]]
@ -581,13 +575,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
name = "wit-bindgen"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
[[package]]
name = "zerocopy"

View file

@ -20,14 +20,14 @@ opt-level = 3
eyre = "0.6.12"
noita_api = {path = "../noita_api"}
shared = {path = "../shared"}
libloading = "0.8.6"
rand = "0.9.0"
rustc-hash = "2.0.0"
libloading = "0.8.8"
rand = "0.9.2"
rustc-hash = "2.1.1"
bimap = "0.6.3"
rayon = "1.10.0"
rayon = "1.11.0"
[features]
#enables cross-compilation on older systems (for example, when compiling on ubuntu 20.04)
#due to unresolved bug in rust toolchain
#https://github.com/rust-lang/rust/issues/79609
pre2204 = []
pre2204 = []

View file

@ -6,7 +6,7 @@ use noita_api::noita::world::ParticleWorldState;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use shared::NoitaOutbound;
use shared::world_sync::{
CHUNK_SIZE, ChunkCoord, CompactPixel, NoitaWorldUpdate, ProxyToWorldSync, WorldSyncToProxy,
CHUNK_SIZE, ChunkCoord, NoitaWorldUpdate, Pixel, ProxyToWorldSync, WorldSyncToProxy,
};
use std::mem::MaybeUninit;
use std::ptr;
@ -23,7 +23,6 @@ impl Module for WorldSync {
return Ok(());
};
let (x, y) = (ent.transform.pos.x, ent.transform.pos.y);
let tmr = std::time::Instant::now();
let updates = (0..1)
//.into_par_iter()
.map(|i| {
@ -33,7 +32,7 @@ impl Module for WorldSync {
let cy = y as i32 / CHUNK_SIZE as i32 + dy;
let mut update = NoitaWorldUpdate {
coord: ChunkCoord(cx, cy),
pixels: std::array::from_fn(|_| None),
pixels: std::array::from_fn(|_| Pixel::default()),
};
if unsafe {
self.particle_world_state
@ -50,16 +49,6 @@ impl Module for WorldSync {
.collect::<Vec<_>>();
let msg = NoitaOutbound::WorldSyncToProxy(WorldSyncToProxy::Updates(updates));
ctx.net.send(&msg)?;
let NoitaOutbound::WorldSyncToProxy(WorldSyncToProxy::Updates(updates)) = msg else {
unreachable!()
};
updates.into_iter().flatten().for_each(|chunk| unsafe {
let _ = self
.particle_world_state
.assume_init_ref()
.decode_world(chunk);
});
noita_api::game_print!("{}", tmr.elapsed().as_nanos());
Ok(())
}
}
@ -84,7 +73,7 @@ trait WorldData {
unsafe fn encode_world(
&self,
coord: ChunkCoord,
chunk: &mut [Option<CompactPixel>; CHUNK_SIZE * CHUNK_SIZE],
chunk: &mut [Pixel; CHUNK_SIZE * CHUNK_SIZE],
) -> eyre::Result<()>;
unsafe fn decode_world(&self, chunk: NoitaWorldUpdate) -> eyre::Result<()>;
}
@ -92,7 +81,7 @@ impl WorldData for ParticleWorldState {
unsafe fn encode_world(
&self,
coord: ChunkCoord,
chunk: &mut [Option<CompactPixel>; CHUNK_SIZE * CHUNK_SIZE],
chunk: &mut [Pixel; CHUNK_SIZE * CHUNK_SIZE],
) -> eyre::Result<()> {
let (cx, cy) = (coord.0 as isize, coord.1 as isize);
let Some(pixel_array) = unsafe { self.world_ptr.as_mut() }
@ -103,11 +92,11 @@ impl WorldData for ParticleWorldState {
return Err(eyre!("chunk not loaded"));
};
let (shift_x, shift_y) = self.get_shift::<CHUNK_SIZE>(cx, cy);
for ((i, j), p) in (shift_x..shift_x + CHUNK_SIZE as isize)
for ((j, i), p) in (shift_x..shift_x + CHUNK_SIZE as isize)
.flat_map(|i| (shift_y..shift_y + CHUNK_SIZE as isize).map(move |j| (i, j)))
.zip(chunk.iter_mut())
{
*p = pixel_array.get_compact_pixel(i, j);
*p = pixel_array.get_pixel(i, j);
}
Ok(())
}
@ -124,17 +113,13 @@ impl WorldData for ParticleWorldState {
let (shift_x, shift_y) = self.get_shift::<CHUNK_SIZE>(cx, cy);
let start_x = cx * CHUNK_SIZE as isize;
let start_y = cy * CHUNK_SIZE as isize;
for (i, pixel) in chunk.pixels.iter().enumerate() {
for (i, pixel) in chunk.pixels.into_iter().enumerate() {
let x = (i % CHUNK_SIZE) as isize;
let y = (i / CHUNK_SIZE) as isize;
let cell = pixel_array.get_mut_raw(shift_x + x, shift_y + y);
let xs = start_x + x;
let ys = start_y + y;
let Some(pixel) = pixel else {
*cell = ptr::null_mut();
continue;
};
let Some(mat) = self.material_list.get_static(pixel.material() as usize) else {
let Some(mat) = self.material_list.get_static(pixel.mat() as usize) else {
return Err(eyre!("mat does not exist"));
};
match mat.cell_type {
@ -171,3 +156,147 @@ impl WorldData for ParticleWorldState {
Ok(())
}
}
#[test]
pub fn test_world() {
use noita_api::noita::types::{
Cell, CellData, CellVTable, CellVTables, Chunk, ChunkMap, GridWorld, GridWorldThreaded,
GridWorldThreadedVTable, GridWorldVTable, NoneCellVTable, StdVec,
};
let mut threaded = GridWorldThreaded {
grid_world_threaded_vtable: &GridWorldThreadedVTable {},
unknown: [0; 287],
update_region: Default::default(),
};
let mut chunks: [*mut Chunk; 512 * 512] = [ptr::null_mut(); 512 * 512];
let chunk_map = ChunkMap {
len: 0,
unknown: 0,
chunk_array: unsafe { std::mem::transmute::<&mut _, &'static mut _>(&mut chunks) },
chunk_count: 0,
min_chunk: Default::default(),
max_chunk: Default::default(),
min_pixel: Default::default(),
max_pixel: Default::default(),
};
let mut grid_world = GridWorld {
vtable: &GridWorldVTable {
unknown: [ptr::null(); 3],
get_chunk_map: ptr::null(),
unknownmagic: ptr::null(),
unknown2: [ptr::null(); 29],
},
rng: 0,
unk: [0; 292],
cam_pos: Default::default(),
cam_dimen: Default::default(),
unknown: [0; 6],
unk_cam: Default::default(),
unk2_cam: Default::default(),
unkown3: 0,
cam: Default::default(),
unkown2: 0,
unk_counter: 0,
world_update_count: 0,
chunk_map,
unknown2: [0; 40],
m_thread_impl: unsafe { std::mem::transmute::<&mut _, &'static mut _>(&mut threaded) },
};
let mut pws = ParticleWorldState {
world_ptr: &mut grid_world,
material_list: StdVec::new(),
cell_vtables: CellVTables(
[CellVTable {
none: &NoneCellVTable {
unknown: [ptr::null(); 41],
},
}; 5],
),
};
for i in 0..256 {
let mut celldata = CellData::default();
celldata.material_type = i;
pws.material_list.push(celldata);
}
let mut list = [0; 512 * 512];
{
let mut data: [*mut Cell; 512 * 512] = [ptr::null_mut(); 512 * 512];
for (i, d) in data.iter_mut().enumerate() {
let mut celldata = CellData::default();
celldata.material_type = rand::random::<u8>() as isize;
list[i] = celldata.material_type;
let cell = Cell::create(
Box::leak(Box::new(celldata)),
CellVTable {
none: &NoneCellVTable {
unknown: [ptr::null_mut(); 41],
},
},
);
*d = Box::leak(Box::new(cell));
}
let chunk = Chunk {
data: unsafe { std::mem::transmute::<&mut _, &'static mut _>(&mut data) },
};
unsafe { pws.world_ptr.as_mut() }
.unwrap()
.chunk_map
.insert(0, 0, chunk);
}
{
let mut data: [*mut Cell; 512 * 512] = [ptr::null_mut(); 512 * 512];
for d in data.iter_mut() {
let celldata = CellData::default();
let cell = Cell::create(
Box::leak(Box::new(celldata)),
CellVTable {
none: &NoneCellVTable {
unknown: [ptr::null_mut(); 41],
},
},
);
*d = Box::leak(Box::new(cell));
}
let chunk = Chunk {
data: unsafe { std::mem::transmute::<&mut _, &'static mut _>(&mut data) },
};
unsafe { pws.world_ptr.as_mut() }
.unwrap()
.chunk_map
.insert(1, 1, chunk);
}
let mut data = [Pixel::default(); CHUNK_SIZE * CHUNK_SIZE];
unsafe {
assert!(pws.encode_world(ChunkCoord(5, 5), &mut data).is_ok());
}
assert_eq!(
data[0..128].iter().map(|a| a.mat()).collect::<Vec<_>>(),
vec![0; 128]
);
let tmr = std::time::Instant::now();
unsafe {
assert!(pws.encode_world(ChunkCoord(0, 0), &mut data).is_ok());
}
println!("{}", tmr.elapsed().as_nanos());
assert_eq!(
data[0..128].iter().map(|a| a.mat()).collect::<Vec<_>>(),
list[0..128].iter().map(|a| *a as u16).collect::<Vec<_>>()
);
let tmr = std::time::Instant::now();
unsafe {
assert!(
pws.decode_world(NoitaWorldUpdate {
coord: ChunkCoord(5, 5),
pixels: data
})
.is_ok()
);
}
println!("{}", tmr.elapsed().as_nanos());
unsafe {
assert!(pws.encode_world(ChunkCoord(0, 0), &mut data).is_ok());
}
assert_eq!(
data[0..128].iter().map(|a| a.mat()).collect::<Vec<_>>(),
list[0..128].iter().map(|a| *a as u16).collect::<Vec<_>>()
);
}

241
noita-proxy/Cargo.lock generated
View file

@ -68,9 +68,9 @@ dependencies = [
[[package]]
name = "alsa"
version = "0.9.2"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdc00893e7a970727e9304671b2c88577b4cfe53dc64019fdfdf9683573a09c4"
checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43"
dependencies = [
"alsa-sys",
"bitflags 2.9.3",
@ -243,9 +243,9 @@ dependencies = [
[[package]]
name = "async-executor"
version = "1.13.2"
version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa"
checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8"
dependencies = [
"async-task",
"concurrent-queue",
@ -1351,14 +1351,14 @@ dependencies = [
[[package]]
name = "fastbloom"
version = "0.9.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27cea6e7f512d43b098939ff4d5a5d6fe3db07971e1d05176fe26c642d33f5b8"
checksum = "18c1ddb9231d8554c2d6bdf4cfaabf0c59251658c68b6c95cd52dd0c513a912a"
dependencies = [
"getrandom 0.3.3",
"libm",
"rand 0.9.2",
"siphasher",
"wide",
]
[[package]]
@ -1652,12 +1652,12 @@ dependencies = [
[[package]]
name = "gethostname"
version = "0.4.3"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55"
dependencies = [
"libc",
"windows-targets 0.48.5",
"rustix 1.0.8",
"windows-targets 0.52.6",
]
[[package]]
@ -1683,7 +1683,7 @@ dependencies = [
"js-sys",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
"wasi 0.14.3+wasi-0.2.4",
"wasm-bindgen",
]
@ -1729,8 +1729,8 @@ dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata 0.4.10",
"regex-syntax 0.8.6",
"regex-automata",
"regex-syntax",
]
[[package]]
@ -2020,7 +2020,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.6.0",
"socket2",
"system-configuration",
"tokio",
"tower-service",
@ -2145,7 +2145,7 @@ dependencies = [
"globset",
"log",
"memchr",
"regex-automata 0.4.10",
"regex-automata",
"same-file",
"walkdir",
"winapi-util",
@ -2169,9 +2169,9 @@ dependencies = [
[[package]]
name = "image-webp"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b"
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
dependencies = [
"byteorder-lite",
"quick-error",
@ -2392,9 +2392,9 @@ dependencies = [
[[package]]
name = "liblzma"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "272b875472a046e39ff7408374a5a050b112d2142211a0f54a295c0bd1c3c757"
checksum = "10bf66f4598dc77ff96677c8e763655494f00ff9c1cf79e2eb5bb07bc31f807d"
dependencies = [
"liblzma-sys",
]
@ -2499,11 +2499,11 @@ dependencies = [
[[package]]
name = "matchers"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
dependencies = [
"regex-automata 0.1.10",
"regex-automata",
]
[[package]]
@ -2700,7 +2700,7 @@ dependencies = [
"serial_test",
"shared",
"shlex",
"socket2 0.6.0",
"socket2",
"steamworks",
"tangled",
"tokio",
@ -2726,12 +2726,11 @@ dependencies = [
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
version = "0.50.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399"
dependencies = [
"overload",
"winapi",
"windows-sys 0.52.0",
]
[[package]]
@ -3235,12 +3234,6 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "owned_ttf_parser"
version = "0.25.1"
@ -3465,9 +3458,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
name = "potential_utf"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
dependencies = [
"zerovec",
]
@ -3559,9 +3552,9 @@ dependencies = [
[[package]]
name = "quinn"
version = "0.11.8"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases",
@ -3570,7 +3563,7 @@ dependencies = [
"quinn-udp",
"rustc-hash 2.1.1",
"rustls",
"socket2 0.5.10",
"socket2",
"thiserror 2.0.16",
"tokio",
"tracing",
@ -3579,9 +3572,9 @@ dependencies = [
[[package]]
name = "quinn-proto"
version = "0.11.12"
version = "0.11.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e"
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
dependencies = [
"bytes",
"fastbloom",
@ -3602,16 +3595,16 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.5.13"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970"
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2 0.5.10",
"socket2",
"tracing",
"windows-sys 0.59.0",
"windows-sys 0.60.2",
]
[[package]]
@ -3750,27 +3743,6 @@ dependencies = [
"thiserror 2.0.16",
]
[[package]]
name = "regex"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.10",
"regex-syntax 0.8.6",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-automata"
version = "0.4.10"
@ -3779,15 +3751,9 @@ checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.6",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.6"
@ -3917,9 +3883,9 @@ dependencies = [
[[package]]
name = "ron"
version = "0.10.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f"
checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468"
dependencies = [
"base64",
"bitflags 2.9.3",
@ -4060,9 +4026,9 @@ dependencies = [
[[package]]
name = "rustls-platform-verifier"
version = "0.5.3"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1"
checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0"
dependencies = [
"core-foundation 0.10.1",
"core-foundation-sys",
@ -4075,7 +4041,7 @@ dependencies = [
"rustls-webpki",
"security-framework 3.3.0",
"security-framework-sys",
"webpki-root-certs 0.26.11",
"webpki-root-certs",
"windows-sys 0.59.0",
]
@ -4110,9 +4076,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "safe_arch"
version = "0.9.2"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb5032219cc30e5bb98749b19a18ceb2cf15e24ba8d517a7e64dff4f1f1eca5"
checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
dependencies = [
"bytemuck",
]
@ -4436,16 +4402,6 @@ dependencies = [
"serde",
]
[[package]]
name = "socket2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "socket2"
version = "0.6.0"
@ -4777,7 +4733,7 @@ dependencies = [
"dashmap",
"quinn",
"rcgen",
"socket2 0.6.0",
"socket2",
"test-log",
"thiserror 2.0.16",
"tokio",
@ -4983,7 +4939,7 @@ dependencies = [
"mio",
"pin-project-lite",
"slab",
"socket2 0.6.0",
"socket2",
"tokio-macros",
"windows-sys 0.59.0",
]
@ -5176,14 +5132,14 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
version = "0.3.19"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"regex-automata",
"sharded-slab",
"smallvec",
"thread_local",
@ -5433,11 +5389,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
version = "0.14.3+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
dependencies = [
"wit-bindgen-rt",
"wit-bindgen",
]
[[package]]
@ -5656,15 +5612,6 @@ dependencies = [
"web-sys",
]
[[package]]
name = "webpki-root-certs"
version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e"
dependencies = [
"webpki-root-certs 1.0.2",
]
[[package]]
name = "webpki-root-certs"
version = "1.0.2"
@ -5797,9 +5744,9 @@ dependencies = [
[[package]]
name = "wide"
version = "0.7.34"
version = "0.7.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a0ab08c041f0cbb00a12fd091b2877dcec2311f90f87a88391d4b0961ffb4fe"
checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
dependencies = [
"bytemuck",
"safe_arch",
@ -5951,21 +5898,6 @@ dependencies = [
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
@ -6005,12 +5937,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
@ -6029,12 +5955,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
@ -6053,12 +5973,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@ -6089,12 +6003,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
@ -6113,12 +6021,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
@ -6137,12 +6039,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
@ -6161,12 +6057,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
@ -6250,13 +6140,10 @@ dependencies = [
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
name = "wit-bindgen"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.3",
]
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
[[package]]
name = "wl-clipboard-rs"
@ -6296,24 +6183,24 @@ dependencies = [
[[package]]
name = "x11rb"
version = "0.13.1"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
dependencies = [
"as-raw-xcb-connection",
"gethostname",
"libc",
"libloading 0.8.8",
"once_cell",
"rustix 0.38.44",
"rustix 1.0.8",
"x11rb-protocol",
]
[[package]]
name = "x11rb-protocol"
version = "0.13.1"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
[[package]]
name = "xcursor"

View file

@ -12,46 +12,46 @@ edition = "2024"
[dependencies]
eframe = { version= "0.32.1", features = ["glow", "default_fonts", "wayland", "x11"], default-features = false }
rfd = "0.15.1"
rfd = "0.15.4"
egui_extras = { version = "0.32.1", features = ["all_loaders"] }
#egui_plot = "0.29.0"
image = { version = "0.25.1", default-features = false, features = ["png", "webp"] }
image = { version = "0.25.6", default-features = false, features = ["png", "webp"] }
wide = "0.7.30"
rayon = "1.10.0"
ron = "0.10.1"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing = "0.1.40"
wide = "0.7.33"
rayon = "1.11.0"
ron = "0.11.0"
tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
tracing = "0.1.41"
tangled = { path = "tangled" }
serde = { version = "1.0.207", features = ["serde_derive", "derive"] }
bitcode = "0.6.3"
lz4_flex = { version = "0.11.3", default-features = false, features = ["std"]}
rand = "0.9.0"
serde = { version = "1.0.219", features = ["serde_derive", "derive"] }
bitcode = "0.6.7"
lz4_flex = { version = "0.11.5", default-features = false, features = ["std"]}
rand = "0.9.2"
steamworks = "0.11.0"
crossbeam = { version = "0.8.4", features = ["crossbeam-channel"] }
arboard = { version = "3.5.0", features = ["wayland-data-control"]}
arboard = { version = "3.6.1", features = ["wayland-data-control"]}
socket2 = { version = "0.6.0", features = ["all"] }
reqwest = { version = "0.12.12", features = ["blocking", "json"]}
reqwest = { version = "0.12.23", features = ["blocking", "json"]}
poll-promise = "0.3.0"
zip = "4.1.0"
self-replace = "1.3.7"
rustc-hash = "2.0.0"
fluent-templates = "0.13.0"
unic-langid = { version = "0.9.5", features = ["serde"] }
zip = "4.5.0"
self-replace = "1.5.0"
rustc-hash = "2.1.1"
fluent-templates = "0.13.1"
unic-langid = { version = "0.9.6", features = ["serde"] }
fluent-bundle = "0.16.0"
argh = "0.1.12"
argh = "0.1.13"
shlex = "1.3.0"
quick-xml = { version = "0.38.0", features = ["serialize"] }
dashmap = "6.0.1"
quick-xml = { version = "0.38.3", features = ["serialize"] }
dashmap = "6.1.0"
eyre = "0.6.12"
tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread"] }
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
tracing-appender = "0.2.3"
shared = {path = "../shared"}
rstar = "0.12.2"
cpal = {version= "0.16.0", features=["jack"]}
rodio = "0.21.0"
rodio = "0.21.1"
opus = "0.3.0"
rubato = "0.16.1"
rubato = "0.16.2"
directories = "6.0.0"
#fundsp = {version = "0.20.0", default-features = false, features = ["std"]}
@ -62,7 +62,7 @@ winapi="0.3.9"
serial_test = "3.2.0"
[build-dependencies]
winresource = "0.1.17"
winresource = "0.1.23"
[profile.dev]
opt-level = 1
@ -72,4 +72,4 @@ lto = true
strip = true
[profile.release-lto]
inherits = "release"
inherits = "release"

View file

@ -37,7 +37,7 @@ use crate::{
bookkeeping::save_state::{SaveState, SaveStateEntry},
};
use shared::des::ProxyToDes;
use shared::world_sync::{ChunkCoord, PixelFlags, ProxyToWorldSync, RawPixel};
use shared::world_sync::{ChunkCoord, Pixel, PixelFlags, ProxyToWorldSync};
use tangled::Reliability;
use tracing::{error, info, warn};
mod audio;
@ -1485,7 +1485,7 @@ pub struct ExplosionData {
ray: u64,
hole: bool,
liquid: bool,
mat: RawPixel,
mat: Pixel,
prob: u8,
}
impl ExplosionData {
@ -1509,10 +1509,7 @@ impl ExplosionData {
ray,
hole,
liquid,
mat: RawPixel {
flags: PixelFlags::Normal,
material: mat,
},
mat: Pixel::new(mat, PixelFlags::Normal),
prob,
}
}

View file

@ -1182,10 +1182,7 @@ impl WorldManager {
let start = x - radius;
let end = x + radius;
let air_pixel = RawPixel {
flags: PixelFlags::Normal,
material: 0,
};
let air_pixel = Pixel::default();
let chunk_storage: Vec<(ChunkCoord, ChunkData)> = self
.chunk_storage
.clone()
@ -1267,10 +1264,7 @@ impl WorldManager {
let dm2 = ((dmx.unsigned_abs() as u64 * dmx.unsigned_abs() as u64
+ dmy.unsigned_abs() as u64 * dmy.unsigned_abs() as u64) as f64)
.recip();
let air_pixel = RawPixel {
flags: PixelFlags::Normal,
material: 0,
};
let air_pixel = Pixel::default();
let close_check = max_cx == min_cx || max_cy == min_cy;
let iter_check = [
(x + r, y),
@ -1370,10 +1364,10 @@ impl WorldManager {
if dx * dx + dy * dy <= r {
let px = icy as usize * CHUNK_SIZE + icx as usize;
if (no_info
|| chunk.pixel(px).flags == PixelFlags::Unknown
|| chunk.pixel(px).flags() == PixelFlags::Unknown
|| self
.materials
.get(&chunk.pixel(px).material)
.get(&chunk.pixel(px).mat())
.map(|(_, _, cell, _)| cell.can_remove(true, false))
.unwrap_or(true))
&& (chance == 100
@ -1418,10 +1412,7 @@ impl WorldManager {
(y - r).div_euclid(CHUNK_SIZE as i32),
(y + r).div_euclid(CHUNK_SIZE as i32),
);
let air_pixel = RawPixel {
flags: PixelFlags::Normal,
material: mat.unwrap_or(0),
};
let air_pixel = Pixel::default();
let (chunkx, chunky) = (
x.div_euclid(CHUNK_SIZE as i32),
y.div_euclid(CHUNK_SIZE as i32),
@ -1475,10 +1466,10 @@ impl WorldManager {
if dd + dy * dy <= rs {
let px = icy as usize * CHUNK_SIZE + icx as usize;
if (no_info
|| chunk.pixel(px).flags == PixelFlags::Unknown
|| chunk.pixel(px).flags() == PixelFlags::Unknown
|| self
.materials
.get(&chunk.pixel(px).material)
.get(&chunk.pixel(px).mat())
.map(|(_, _, cell, _)| cell.can_remove(true, false))
.unwrap_or(true))
&& (chance == 100
@ -1581,7 +1572,7 @@ impl WorldManager {
let icy = y.rem_euclid(CHUNK_SIZE as i32);
let px = icy as usize * CHUNK_SIZE + icx as usize;
let pixel = working_chunk.pixel(px);
if let Some(stats) = self.materials.get(&pixel.material) {
if let Some(stats) = self.materials.get(&pixel.mat()) {
let h = (stats.1 as f64 * mult as f64) as u64;
if stats.0 > d || ray < h {
return (last_coord, 0, None);
@ -1724,7 +1715,7 @@ impl WorldManager {
list: Vec<(u64, u64, Option<ChunkCoord>)>,
hole: bool,
liquid: bool,
mat: RawPixel,
mat: Pixel,
prob: u8,
r: u64,
) -> Vec<ExRet> {
@ -1741,10 +1732,7 @@ impl WorldManager {
(y - r as i32).div_euclid(CHUNK_SIZE as i32),
(y + r as i32).div_euclid(CHUNK_SIZE as i32),
);
let air_pixel = RawPixel {
flags: PixelFlags::Normal,
material: 0,
};
let air_pixel = Pixel::default();
let (chunkx, chunky) = (
x.div_euclid(CHUNK_SIZE as i32),
y.div_euclid(CHUNK_SIZE as i32),
@ -1888,7 +1876,7 @@ impl WorldManager {
} {
if self
.materials
.get(&chunk.pixel(px).material)
.get(&chunk.pixel(px).mat())
.map(|(dur, _, cell, _)| *dur <= d && cell.can_remove(hole, liquid))
.unwrap_or(true)
{
@ -2047,10 +2035,7 @@ impl WorldManager {
grouped.entry(key).or_default().push((a, b));
}
let data: Vec<(usize, Vec<(usize, u64)>)> = grouped.into_iter().collect();
let air_pixel = RawPixel {
flags: PixelFlags::Normal,
material: 0,
};
let air_pixel = Pixel::default();
let mut chunk = Chunk::default();
let mut chunk_delta = Chunk::default();
self.chunk_storage.get(&coord)?.apply_to_chunk(&mut chunk);
@ -2109,7 +2094,7 @@ impl WorldManager {
data.iter().any(|(i, r)| j == *i && dd <= *r)
}) && self
.materials
.get(&chunk.pixel(px).material)
.get(&chunk.pixel(px).mat())
.map(|(dur, _, cell, _)| *dur <= d && cell.can_remove(hole, liquid))
.unwrap_or(true)
{
@ -2203,7 +2188,7 @@ impl WorldManager {
let icy = y.rem_euclid(CHUNK_SIZE as i32);
let px = icy as usize * CHUNK_SIZE + icx as usize;
let pixel = working_chunk.pixel(px);
if let Some(stats) = self.materials.get(&pixel.material) {
if let Some(stats) = self.materials.get(&pixel.mat()) {
let h = (stats.1 as f64 * mult as f64) as u64;
avg += h;
count2 += 1;
@ -2303,7 +2288,7 @@ impl WorldManager {
}
let p = icy as usize * CHUNK_SIZE + icx as usize;
*px = image::Luma([
((working_chunk.pixel(p).material * 255) as usize / self.materials.len()) as u8
((working_chunk.pixel(p).mat() * 255) as usize / self.materials.len()) as u8
])
}
}
@ -2318,8 +2303,8 @@ fn create_image(chunk: ChunkData, materials: &FxHashMap<u16, u32>) -> RgbaImage
let y = i / w as usize;
let p = y * CHUNK_SIZE + x;
let m = working_chunk.pixel(p);
if m.flags != PixelFlags::Unknown
&& let Some(c) = materials.get(&m.material)
if m.flags() != PixelFlags::Unknown
&& let Some(c) = materials.get(&m.mat())
{
let a = (c >> 24) & 0xFFu32;
let r = (c >> 16) & 0xFFu32;
@ -3077,7 +3062,7 @@ use rand::seq::SliceRandom;
#[cfg(test)]
use serial_test::serial;
use shared::world_sync::{
CHUNK_SIZE, ChunkCoord, NoitaWorldUpdate, PixelFlags, RawPixel, WorldSyncToProxy,
CHUNK_SIZE, ChunkCoord, NoitaWorldUpdate, Pixel, PixelFlags, WorldSyncToProxy,
};
#[cfg(test)]
#[test]

View file

@ -1,13 +1,10 @@
use std::num::NonZeroU16;
use std::sync::Arc;
use bitcode::{Decode, Encode};
use chunk::Chunk;
use encoding::PixelRunner;
use rustc_hash::{FxHashMap, FxHashSet};
use shared::world_sync::{
CHUNK_SIZE, ChunkCoord, CompactPixel, NoitaWorldUpdate, PixelRun, RawPixel,
};
use shared::world_sync::{CHUNK_SIZE, ChunkCoord, NoitaWorldUpdate, Pixel, PixelRun};
use tracing::info;
pub(crate) mod chunk;
pub mod encoding;
@ -24,14 +21,14 @@ pub(crate) struct WorldModel {
/// Kinda close to ChunkDelta, but doesn't assume we know anything about the chunk.
#[derive(Debug, Encode, Decode, Clone)]
pub(crate) struct ChunkData {
pub runs: Vec<PixelRun<CompactPixel>>,
pub runs: Vec<PixelRun<Pixel>>,
}
/// Contains a diff, only pixels that were updated, for a given chunk.
#[derive(Debug, Encode, Decode, Clone)]
pub(crate) struct ChunkDelta {
pub chunk_coord: ChunkCoord,
runs: Arc<Vec<PixelRun<Option<CompactPixel>>>>,
runs: Arc<Vec<PixelRun<Option<Pixel>>>>,
}
impl ChunkData {
@ -54,26 +51,20 @@ impl ChunkData {
pub(crate) fn new(mat: u16) -> Self {
let mut runner = PixelRunner::new();
for _ in 0..CHUNK_SIZE * CHUNK_SIZE {
runner.put_pixel(
RawPixel {
flags: shared::world_sync::PixelFlags::Normal,
material: mat,
}
.to_compact(),
)
runner.put_pixel(Pixel::new(mat, shared::world_sync::PixelFlags::Normal))
}
let runs = runner.build();
ChunkData { runs }
}
pub(crate) fn apply_to_chunk(&self, chunk: &mut Chunk) {
let nil = CompactPixel(NonZeroU16::new(4095).unwrap());
let nil = Pixel::NIL;
let mut offset = 0;
for run in &self.runs {
let pixel = run.data;
if pixel != nil {
for _ in 0..run.length {
chunk.set_compact_pixel(offset, pixel);
chunk.set_pixel(offset, pixel);
offset += 1;
}
} else {
@ -82,14 +73,14 @@ impl ChunkData {
}
}
pub(crate) fn apply_delta(&mut self, delta: ChunkData) {
let nil = CompactPixel(NonZeroU16::new(4095).unwrap());
let nil = Pixel::NIL;
let mut chunk = Chunk::default();
self.apply_to_chunk(&mut chunk);
let mut offset = 0;
for run in delta.runs.iter() {
if run.data != nil {
for _ in 0..run.length {
chunk.set_compact_pixel(offset, run.data);
chunk.set_pixel(offset, run.data);
offset += 1;
}
} else {
@ -133,7 +124,7 @@ impl WorldModel {
update: NoitaWorldUpdate,
changed: &mut FxHashSet<ChunkCoord>,
) {
fn set_pixel(pixel: RawPixel, chunk: &mut Chunk, offset: usize) -> bool {
fn set_pixel(pixel: Pixel, chunk: &mut Chunk, offset: usize) -> bool {
let current = chunk.pixel(offset);
if current != pixel {
chunk.set_pixel(offset, pixel);
@ -158,7 +149,7 @@ impl WorldModel {
chunk_coord = new_chunk_coord;
chunk = self.chunks.entry(chunk_coord).or_default();
}
if set_pixel(RawPixel::from_opt_compact(pixel), chunk, offset) {
if set_pixel(pixel, chunk, offset) {
self.updated_chunks.insert(chunk_coord);
if changed.contains(&chunk_coord) {
changed.remove(&chunk_coord);
@ -173,7 +164,7 @@ impl WorldModel {
if let Some(chunk) = self.chunks.get_mut(&coord) {
updates.push(NoitaWorldUpdate {
coord,
pixels: chunk.pixels.map(CompactPixel::from_material),
pixels: chunk.pixels,
});
}
}
@ -187,7 +178,7 @@ impl WorldModel {
for run in delta.runs.iter() {
if let Some(pixel) = run.data {
for _ in 0..run.length {
chunk.set_compact_pixel(offset, pixel);
chunk.set_pixel(offset, pixel);
offset += 1;
}
} else {
@ -204,7 +195,7 @@ impl WorldModel {
let chunk = self.chunks.get(&chunk_coord)?;
let mut runner = PixelRunner::new();
for i in 0..CHUNK_SIZE * CHUNK_SIZE {
runner.put_pixel((ignore_changed || chunk.changed(i)).then(|| chunk.compact_pixel(i)))
runner.put_pixel((ignore_changed || chunk.changed(i)).then(|| chunk.pixel(i)))
}
let runs = runner.build().into();
Some(ChunkDelta { chunk_coord, runs })

View file

@ -1,8 +1,8 @@
use super::{ChunkData, encoding::PixelRunner};
use shared::world_sync::{CHUNK_SIZE, CompactPixel, RawPixel};
use shared::world_sync::{CHUNK_SIZE, Pixel};
pub struct Chunk {
pub pixels: [u16; CHUNK_SQUARE],
pub pixels: [Pixel; CHUNK_SQUARE],
changed: Changed<bool, CHUNK_SQUARE>,
any_changed: bool,
}
@ -53,7 +53,7 @@ fn test_changed() {
impl Default for Chunk {
fn default() -> Self {
Self {
pixels: [4095; CHUNK_SQUARE],
pixels: [Pixel::NIL; CHUNK_SQUARE],
changed: Changed([false; CHUNK_SQUARE]),
any_changed: false,
}
@ -62,29 +62,17 @@ impl Default for Chunk {
/// Chunk of pixels. Stores pixels and tracks if they were changed.
impl Chunk {
pub fn pixel(&self, offset: usize) -> RawPixel {
RawPixel::from_compact(CompactPixel::from_raw(self.pixels[offset]))
pub fn pixel(&self, offset: usize) -> Pixel {
self.pixels[offset]
}
pub fn compact_pixel(&self, offset: usize) -> CompactPixel {
CompactPixel::from_raw(self.pixels[offset])
}
pub fn set_pixel(&mut self, offset: usize, pixel: RawPixel) {
let px = pixel.to_compact().raw();
if self.pixels[offset] != px {
self.pixels[offset] = px;
pub fn set_pixel(&mut self, offset: usize, pixel: Pixel) {
if self.pixels[offset] != pixel {
self.pixels[offset] = pixel;
self.mark_changed(offset);
}
}
pub fn set_compact_pixel(&mut self, offset: usize, pixel: CompactPixel) {
let px = pixel.raw();
if self.pixels[offset] != px {
self.pixels[offset] = px;
self.mark_changed(offset);
}
}
pub fn changed(&self, offset: usize) -> bool {
self.changed.get(offset)
}
@ -102,7 +90,7 @@ impl Chunk {
pub fn to_chunk_data(&self) -> ChunkData {
let mut runner = PixelRunner::new();
for i in 0..CHUNK_SQUARE {
runner.put_pixel(self.compact_pixel(i))
runner.put_pixel(self.pixel(i))
}
let runs = runner.build();
ChunkData { runs }

View file

@ -13,16 +13,16 @@ name = "chat"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
crossbeam = "0.8.2"
tracing = "0.1.36"
dashmap = "6.0.1"
quinn = "0.11.5"
rcgen = "0.14.2"
thiserror = "2.0.3"
tokio = { version = "1.40.0", features = ["macros", "io-util", "sync"] }
bitcode = "0.6.3"
crossbeam = "0.8.4"
tracing = "0.1.41"
dashmap = "6.1.0"
quinn = "0.11.9"
rcgen = "0.14.3"
thiserror = "2.0.16"
tokio = { version = "1.47.1", features = ["macros", "io-util", "sync"] }
bitcode = "0.6.7"
socket2 = "0.6.0"
[dev-dependencies]
test-log = { version = "0.2.16", default-features = false, features = ["trace"]}
tracing-subscriber = {version = "0.3", features = ["env-filter", "fmt"]}
test-log = { version = "0.2.18", default-features = false, features = ["trace"]}
tracing-subscriber = {version = "0.3", features = ["env-filter", "fmt"]}

View file

@ -5,12 +5,12 @@ edition = "2024"
[dependencies]
eyre = "0.6.12"
libloading = "0.8.5"
libloading = "0.8.8"
noita_api_macro = {path = "noita_api_macro"}
shared = {path = "../shared"}
base64 = "0.22.1"
rustc-hash = "2.0.0"
rustc-hash = "2.1.1"
smallvec = "1.15.1"
object = "0.37.1"
rayon = "1.10.0"
iced-x86 = "1.21.0"
object = "0.37.3"
rayon = "1.11.0"
iced-x86 = "1.21.0"

View file

@ -8,7 +8,7 @@ proc-macro = true
[dependencies]
heck = "0.5.0"
proc-macro2 = "1.0.89"
quote = "1.0.37"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
proc-macro2 = "1.0.101"
quote = "1.0.40"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.143"

View file

@ -1,12 +1,13 @@
use crate::noita::types::objects::{ConfigExplosion, ConfigGridCosmeticParticle};
use crate::noita::types::{StdMap, StdString, StdVec, ThiscallFn, Vec2, Vec2i};
use shared::world_sync::{CompactPixel, PixelFlags, RawPixel};
use shared::world_sync::{Pixel, PixelFlags};
use std::ffi::c_void;
use std::fmt::{Debug, Formatter};
use std::slice;
#[repr(usize)]
#[derive(Debug, PartialEq, Clone, Copy)]
#[derive(Debug, PartialEq, Clone, Copy, Default)]
pub enum CellType {
#[default]
None = 0,
Liquid = 1,
Gas = 2,
@ -15,7 +16,7 @@ pub enum CellType {
}
#[repr(C)]
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct CellGraphics {
pub texture_file: StdString,
pub color: Color,
@ -34,7 +35,7 @@ pub struct StatusEffect {
pub duration: f32,
}
#[repr(C)]
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct CellData {
pub name: StdString,
pub ui_name: StdString,
@ -212,7 +213,7 @@ pub struct SolidCellVTable {
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct NoneCellVTable {
unknown: [*const ThiscallFn; 41],
pub unknown: [*const ThiscallFn; 41],
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
@ -273,7 +274,7 @@ pub struct LiquidCellVTable {
#[repr(C)]
#[derive(Clone, Debug, Copy)]
pub struct Cell {
pub vtable: &'static CellVTable,
pub vtable: CellVTable,
pub hp: isize,
unknown1: [isize; 2],
@ -342,12 +343,7 @@ impl FireCell {
} else {
-1
};
let mut cell = Cell::create(mat, unsafe {
(vtable as *const FireCellVTable)
.cast::<CellVTable>()
.as_ref()
.unwrap()
});
let mut cell = Cell::create(mat, CellVTable { fire: vtable });
cell.is_burning = true;
Self {
cell,
@ -395,12 +391,7 @@ impl GasCell {
} else {
(false, -1)
};
let mut cell = Cell::create(mat, unsafe {
(vtable as *const GasCellVTable)
.cast::<CellVTable>()
.as_ref()
.unwrap()
});
let mut cell = Cell::create(mat, CellVTable { gas: vtable });
cell.is_burning = true;
Self {
cell,
@ -457,12 +448,7 @@ impl LiquidCell {
-1
};
Self {
cell: Cell::create(mat, unsafe {
(vtable as *const LiquidCellVTable)
.cast::<CellVTable>()
.as_ref()
.unwrap()
}),
cell: Cell::create(mat, CellVTable { liquid: vtable }),
x: 0,
y: 0,
unknown1: 3,
@ -481,7 +467,7 @@ impl LiquidCell {
}
impl Cell {
fn create(material: &'static CellData, vtable: &'static CellVTable) -> Self {
pub fn create(material: &'static CellData, vtable: CellVTable) -> Self {
Self {
vtable,
hp: material.hp,
@ -650,53 +636,30 @@ impl Chunk {
&mut self.data[index.cast_unsigned()]
}
#[inline]
pub fn get_raw_pixel(&self, x: isize, y: isize) -> RawPixel {
pub fn get_pixel(&self, x: isize, y: isize) -> Pixel {
if let Some(cell) = self.get(x, y) {
if cell.material.cell_type == CellType::Liquid {
RawPixel {
material: cell.material.material_type as u16,
flags: if cell.get_liquid().is_static == cell.material.liquid_static {
Pixel::new(
cell.material.material_type as u16,
if cell.get_liquid().is_static == cell.material.liquid_static {
PixelFlags::Normal
} else {
PixelFlags::Abnormal
},
}
)
} else {
RawPixel {
material: cell.material.material_type as u16,
flags: PixelFlags::Normal,
}
Pixel::new(cell.material.material_type as u16, PixelFlags::Normal)
}
} else {
RawPixel {
material: 0,
flags: PixelFlags::Normal,
}
Pixel::new(0, PixelFlags::Normal)
}
}
#[inline]
pub fn get_compact_pixel(&self, x: isize, y: isize) -> Option<CompactPixel> {
self.get(x, y).map(|cell| {
let mat = (cell.material.material_type as u16 + 1) << 1;
CompactPixel(if cell.material.cell_type == CellType::Liquid {
(mat | if cell.get_liquid().is_static == cell.material.liquid_static {
PixelFlags::Normal
} else {
PixelFlags::Abnormal
} as u16)
.try_into()
.unwrap()
} else {
(mat | PixelFlags::Normal as u16).try_into().unwrap()
})
})
}
}
#[repr(C)]
pub struct ChunkMap {
pub len: usize,
unknown: isize,
pub unknown: isize,
pub chunk_array: &'static mut [*mut Chunk; 512 * 512],
pub chunk_count: usize,
pub min_chunk: Vec2i,
@ -761,16 +724,21 @@ impl ChunkMap {
let index = (((y - 256) & 511) << 9) | ((x - 256) & 511);
unsafe { self.chunk_array[index.cast_unsigned()].as_mut() }
}
#[inline]
pub fn insert(&mut self, x: isize, y: isize, chunk: Chunk) {
let index = (((y - 256) & 511) << 9) | ((x - 256) & 511);
self.chunk_array[index.cast_unsigned()] = Box::leak(Box::new(chunk))
}
}
#[repr(C)]
#[derive(Debug)]
pub struct GridWorldVTable {
//ptr is 0x10013bc
unknown: [*const ThiscallFn; 3],
pub unknown: [*const ThiscallFn; 3],
pub get_chunk_map: *const ThiscallFn,
unknownmagic: *const ThiscallFn,
unknown2: [*const ThiscallFn; 29],
pub unknownmagic: *const ThiscallFn,
pub unknown2: [*const ThiscallFn; 29],
}
#[repr(C)]
@ -800,7 +768,7 @@ pub struct GridWorldThreadedVTable {
#[derive(Debug)]
pub struct GridWorldThreaded {
pub grid_world_threaded_vtable: &'static GridWorldThreadedVTable,
unknown: [isize; 287],
pub unknown: [isize; 287],
pub update_region: AABB,
}
@ -809,19 +777,19 @@ pub struct GridWorldThreaded {
pub struct GridWorld {
pub vtable: &'static GridWorldVTable,
pub rng: isize,
unk: [isize; 292],
pub unk: [isize; 292],
pub cam_pos: Vec2i,
pub cam_dimen: Vec2i,
unknown: [isize; 6],
unk_cam: IAABB,
unk2_cam: IAABB,
unkown3: isize,
pub unknown: [isize; 6],
pub unk_cam: IAABB,
pub unk2_cam: IAABB,
pub unkown3: isize,
pub cam: IAABB,
unkown2: isize,
unk_counter: isize,
pub unkown2: isize,
pub unk_counter: isize,
pub world_update_count: isize,
pub chunk_map: ChunkMap,
unknown2: [isize; 40],
pub unknown2: [isize; 40],
pub m_thread_impl: &'static mut GridWorldThreaded,
}
#[repr(C)]

View file

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
bitcode = "0.6.3"
bitcode = "0.6.7"
eyre = "0.6.12"
tracing = "0.1.41"
strum = { version = "0.27.0", features = ["derive"] }
strum = { version = "0.27.2", features = ["derive"] }

View file

@ -1,5 +1,4 @@
use bitcode::{Decode, Encode};
use std::num::NonZeroU16;
/// Stores a run of pixels.
/// Not specific to Noita side - length is an actual length
#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)]
@ -16,101 +15,52 @@ pub struct ChunkCoord(pub i32, pub i32);
#[derive(Debug, Encode, Decode, Clone)]
pub struct NoitaWorldUpdate {
pub coord: ChunkCoord,
pub pixels: [Option<CompactPixel>; CHUNK_SIZE * CHUNK_SIZE],
pub pixels: [Pixel; CHUNK_SIZE * CHUNK_SIZE],
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Encode, Decode)]
pub enum PixelFlags {
/// Actual material isn't known yet.
Normal = 0,
Abnormal = 1,
#[default]
Unknown = 0,
Normal = 32768,
Abnormal = 16384,
}
const BITS: u16 = 8191;
#[derive(Debug, Encode, Decode, PartialEq, Eq, Clone, Copy)]
pub struct RawPixel {
pub material: u16,
pub flags: PixelFlags,
}
impl RawPixel {
pub fn to_compact(self) -> CompactPixel {
let flag_bit = if self.flags == PixelFlags::Normal {
0
} else {
1
};
let material = self.material & BITS; // 11 bits for material
let raw = if self.flags == PixelFlags::Unknown {
CompactPixel::UNKNOWN_RAW
} else {
(material << 1) | flag_bit
};
CompactPixel(NonZeroU16::new(raw).unwrap())
}
pub fn from_compact(compact: CompactPixel) -> Self {
let raw = compact.raw();
let material = compact.material();
let flags = compact.flags();
if raw == CompactPixel::UNKNOWN_RAW {
RawPixel {
flags: PixelFlags::Unknown,
material: 0,
}
} else {
RawPixel { flags, material }
}
}
pub fn from_opt_compact(compact: Option<CompactPixel>) -> Self {
if let Some(pixel) = compact {
Self::from_compact(pixel)
} else {
RawPixel {
material: 0,
flags: PixelFlags::Normal,
}
}
}
Unknown = 15,
//may have at most * = 15
}
/// An entire pixel packed into 12 bits.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode, Default)]
#[repr(transparent)]
pub struct CompactPixel(pub NonZeroU16);
pub struct Pixel(u16);
impl CompactPixel {
const UNKNOWN_RAW: u16 = BITS + 1;
pub fn from_raw(val: u16) -> Self {
CompactPixel(NonZeroU16::new(val).unwrap())
}
pub fn from_material(val: u16) -> Option<Self> {
if val == 0 {
None
} else {
Some(CompactPixel(NonZeroU16::new(val).unwrap()))
}
}
pub fn raw(self) -> u16 {
u16::from(self.0)
}
pub fn material(self) -> u16 {
self.raw() & BITS
}
pub fn flags(self) -> PixelFlags {
if self.raw() & 1 == 1 {
PixelFlags::Abnormal
} else {
PixelFlags::Normal
}
}
#[test]
fn test() {
let p = Pixel::new(0, PixelFlags::Unknown);
assert_eq!(p.mat(), 0);
assert_eq!(p.flags(), PixelFlags::Unknown);
let p = Pixel::new(0, PixelFlags::Normal);
assert_eq!(p.mat(), 0);
assert_eq!(p.flags(), PixelFlags::Normal);
let p = Pixel::new(15, PixelFlags::Unknown);
assert_eq!(p.mat(), 15);
assert_eq!(p.flags(), PixelFlags::Unknown);
let p = Pixel::new(15, PixelFlags::Normal);
assert_eq!(p.mat(), 15);
assert_eq!(p.flags(), PixelFlags::Normal);
}
impl Default for CompactPixel {
fn default() -> Self {
Self(NonZeroU16::new(CompactPixel::UNKNOWN_RAW).unwrap())
impl Pixel {
pub const NIL: Pixel = Pixel::new(0, PixelFlags::Abnormal);
//mat must be less then 13 bits
pub const fn new(mat: u16, flag: PixelFlags) -> Self {
Self(mat | ((flag as u16) << 12))
}
pub fn mat(self) -> u16 {
self.0 & 0x0FFF
}
pub fn flags(self) -> PixelFlags {
unsafe { std::mem::transmute((self.0 >> 12) as u8) }
}
}