Remove unused runtime code and dependencies

This commit is contained in:
Bulat Fatykh
2026-09-30 07:53:22 +03:00
committed by vtroc7
parent b36dcc96e9
commit b7f04c53f3
28 changed files with 11 additions and 1316 deletions
Generated
-48
View File
@@ -290,7 +290,6 @@ dependencies = [
"fastfile_iw4",
"fastfile_iw5",
"fastfile_t5",
"weapon_iw4",
"xmodel_runtime",
]
@@ -367,7 +366,6 @@ dependencies = [
name = "asset_model"
version = "0.1.0"
dependencies = [
"anim_iw4",
"asset_core",
"asset_iw4",
"asset_material",
@@ -415,7 +413,6 @@ dependencies = [
"fastfile_t5",
"fx_iw4",
"lighting_iw4",
"trace_iw4",
"weapon_iw4",
"xmodel_runtime",
]
@@ -424,7 +421,6 @@ dependencies = [
name = "assets"
version = "0.1.0"
dependencies = [
"anim_iw4",
"asset_anim",
"asset_audio",
"asset_core",
@@ -435,22 +431,18 @@ dependencies = [
"asset_transport",
"asset_world",
"async-lock",
"bcdec_rs",
"bevy",
"clipmap_iw4",
"diag",
"dpvs_iw4",
"fastfile_iw4",
"fastfile_iw5",
"fastfile_t5",
"frame",
"fx_iw4",
"libc",
"lighting_iw4",
"png",
"render_material",
"serde_json",
"trace_iw4",
"weapon_iw4",
"xmodel_runtime",
]
@@ -577,14 +569,12 @@ dependencies = [
"frame",
"gamemode_iw4",
"hud_iw4",
"killcam_iw4",
"movement_iw4",
"net",
"perf",
"playerstate_iw4",
"sim",
"symphonia",
"weapon_iw4",
]
[[package]]
@@ -1978,7 +1968,6 @@ dependencies = [
"entity_iw4",
"frame",
"gamemode_iw4",
"glam",
"math_iw4",
"movement_iw4",
"net",
@@ -2185,15 +2174,12 @@ dependencies = [
"bevy",
"bots",
"diag",
"dpvs_iw4",
"entity_iw4",
"frame",
"hud",
"input_iw4",
"math_iw4",
"net",
"perf",
"playerstate_iw4",
"render",
"render_frontend",
"render_fx",
@@ -3252,7 +3238,6 @@ dependencies = [
"frame",
"gamemode_iw4",
"hud_iw4",
"killcam_iw4",
"math_iw4",
"movement_iw4",
"net",
@@ -3505,7 +3490,6 @@ dependencies = [
"rustls-pemfile",
"rustls-platform-verifier",
"tokio",
"tokio-util",
]
[[package]]
@@ -3612,7 +3596,6 @@ name = "launcher"
version = "0.1.0"
dependencies = [
"asset_transport",
"assets",
"bootstrap",
"diag",
]
@@ -5003,35 +4986,16 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
name = "render"
version = "0.1.0"
dependencies = [
"anim_iw4",
"asset_iw4",
"asset_world",
"assets",
"audio",
"bevy",
"bytemuck",
"d3d9_sm3",
"d3d9_state",
"diag",
"dpvs_iw4",
"entity_iw4",
"fastfile_iw4",
"frame",
"fx",
"fx_iw4",
"gamemode_iw4",
"hud",
"hud_iw4",
"lighting_iw4",
"marks_iw4",
"math_iw4",
"miniz_oxide",
"naga",
"net",
"perf",
"playerstate_iw4",
"render_anim",
"render_backend",
"render_frame",
"render_frontend",
"render_fx",
@@ -5039,8 +5003,6 @@ dependencies = [
"render_scene",
"serde",
"serde_json",
"sim",
"weapon_iw4",
]
[[package]]
@@ -5066,7 +5028,6 @@ dependencies = [
"frame",
"fx",
"fx_iw4",
"gamemode_iw4",
"hud_iw4",
"lighting_iw4",
"math_iw4",
@@ -5125,17 +5086,14 @@ dependencies = [
"audio",
"bevy",
"bytemuck",
"d3d9_decl",
"d3d9_sm3",
"d3d9_state",
"diag",
"dpvs_iw4",
"entity_iw4",
"fastfile_iw4",
"frame",
"fx",
"fx_iw4",
"gamemode_iw4",
"hud_iw4",
"lighting_iw4",
"marks_iw4",
@@ -5143,7 +5101,6 @@ dependencies = [
"naga",
"net",
"perf",
"playerstate_iw4",
"render_anim",
"render_frame",
"render_fx",
@@ -5194,7 +5151,6 @@ dependencies = [
"assets",
"bevy",
"bytemuck",
"d3d9_decl",
"d3d9_sm3",
"d3d9_state",
"diag",
@@ -5258,7 +5214,6 @@ dependencies = [
"diag",
"frame",
"getrandom 0.3.4",
"movement_iw4",
"net",
"perf",
"playerstate_iw4",
@@ -5577,7 +5532,6 @@ dependencies = [
"assets",
"audio",
"bevy",
"bots",
"clipmap_iw4",
"diag",
"frame",
@@ -5585,7 +5539,6 @@ dependencies = [
"hud_iw4",
"net",
"perf",
"render",
"render_frontend",
"render_fx",
"sim",
@@ -6299,7 +6252,6 @@ dependencies = [
"diag",
"frame",
"net",
"session",
"sim",
]
-1
View File
@@ -13,7 +13,6 @@ anim_iw4.workspace = true
fastfile_iw4.workspace = true
fastfile_iw5.workspace = true
fastfile_t5.workspace = true
weapon_iw4.workspace = true
xmodel_runtime.workspace = true
bevy.workspace = true
-1
View File
@@ -9,7 +9,6 @@ description = "XModel, skeleton, mesh, lighting, FPV, body, and projectile produ
asset_core.workspace = true
asset_material.workspace = true
asset_iw4.workspace = true
anim_iw4.workspace = true
fastfile_iw4.workspace = true
fastfile_iw5.workspace = true
fastfile_t5.workspace = true
-1
View File
@@ -16,7 +16,6 @@ fastfile_iw5.workspace = true
fastfile_t5.workspace = true
dpvs_iw4.workspace = true
clipmap_iw4.workspace = true
trace_iw4.workspace = true
lighting_iw4.workspace = true
fx_iw4.workspace = true
weapon_iw4.workspace = true
-5
View File
@@ -8,7 +8,6 @@ description = "Asset lane orchestration, linking and conversion into engine obje
[dependencies]
render_material.workspace = true
diag.workspace = true
anim_iw4.workspace = true
xmodel_runtime.workspace = true
asset_core.workspace = true
asset_anim.workspace = true
@@ -23,15 +22,11 @@ fastfile_iw4.workspace = true
fastfile_t5.workspace = true
fastfile_iw5.workspace = true
asset_iw4.workspace = true
dpvs_iw4.workspace = true
clipmap_iw4.workspace = true
trace_iw4.workspace = true
# Light-grid CPU sample chain for authored smodel `$model_lighting` tiles.
lighting_iw4.workspace = true
fx_iw4.workspace = true
bevy.workspace = true
frame.workspace = true
bcdec_rs.workspace = true
serde_json.workspace = true
async-lock.workspace = true
png.workspace = true
-2
View File
@@ -14,7 +14,6 @@ asset_game.workspace = true
asset_transport.workspace = true
assets.workspace = true
asset_iw4.workspace = true
weapon_iw4.workspace = true
movement_iw4.workspace = true
frame.workspace = true
entity_iw4.workspace = true
@@ -22,7 +21,6 @@ net.workspace = true
sim.workspace = true
hud_iw4 = { path = "../hud_iw4" }
playerstate_iw4.workspace = true
killcam_iw4.workspace = true
gamemode_iw4.workspace = true
perf.workspace = true
symphonia = { version = "0.5", default-features = false, features = ["mp3", "pcm", "wav", "adpcm"] }
-1
View File
@@ -19,7 +19,6 @@ movement_iw4 = { path = "../movement_iw4" }
weapon_iw4 = { path = "../weapon_iw4" }
math_iw4 = { path = "../math_iw4" }
trace_iw4.workspace = true
glam.workspace = true
gamemode_iw4.workspace = true
[lints]
-3
View File
@@ -7,8 +7,6 @@ description = "Our console: input, parsing, execution, cvar storage, coverage re
[dependencies]
diag.workspace = true
math_iw4.workspace = true
dpvs_iw4.workspace = true
bevy.workspace = true
frame.workspace = true
ui.workspace = true
@@ -19,7 +17,6 @@ asset_world.workspace = true
assets = { path = "../assets" }
audio = { path = "../audio" }
input_iw4.workspace = true
playerstate_iw4.workspace = true
net = { path = "../net" }
render = { path = "../render" }
render_frontend.workspace = true
-1
View File
@@ -5,7 +5,6 @@ mod asset_type;
mod content;
mod envelope;
mod load;
pub mod shader;
mod stream;
mod wire;
mod zone;
-736
View File
@@ -1,736 +0,0 @@
use core::fmt;
const END: u16 = 0xffff;
const COMMENT: u16 = 0xfffe;
const CTAB: u32 = 0x4241_5443;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderKind {
Pixel,
Vertex,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ShaderVersion {
pub kind: ShaderKind,
pub major: u8,
pub minor: u8,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderError {
Empty,
UnalignedBytes(usize),
UnsupportedVersion(u32),
Truncated {
at_word: usize,
needed: usize,
have: usize,
},
MissingEnd,
TrailingWords(usize),
MalformedCtab,
}
impl fmt::Display for ShaderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Empty => f.write_str("shader has no version token"),
Self::UnalignedBytes(len) => write!(f, "shader length {len} is not DWORD-aligned"),
Self::UnsupportedVersion(version) => {
write!(f, "unsupported shader version {version:#010x}")
}
Self::Truncated {
at_word,
needed,
have,
} => write!(
f,
"token at word {at_word} needs {needed} words, only {have} remain"
),
Self::MissingEnd => f.write_str("shader has no END token"),
Self::TrailingWords(words) => write!(f, "END is followed by {words} words"),
Self::MalformedCtab => f.write_str("malformed CTAB comment"),
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct Shader<'a> {
bytes: &'a [u8],
version: ShaderVersion,
}
impl<'a> Shader<'a> {
pub fn parse(bytes: &'a [u8]) -> Result<Self, ShaderError> {
if bytes.is_empty() {
return Err(ShaderError::Empty);
}
if !bytes.len().is_multiple_of(4) {
return Err(ShaderError::UnalignedBytes(bytes.len()));
}
let version_word = word(bytes, 0).ok_or(ShaderError::Empty)?;
let kind = match version_word >> 16 {
0xffff => ShaderKind::Pixel,
0xfffe => ShaderKind::Vertex,
_ => return Err(ShaderError::UnsupportedVersion(version_word)),
};
let version = ShaderVersion {
kind,
major: ((version_word >> 8) & 0xff) as u8,
minor: (version_word & 0xff) as u8,
};
if version.major != 3 || version.minor != 0 {
return Err(ShaderError::UnsupportedVersion(version_word));
}
let words = bytes.len() / 4;
let mut at = 1;
loop {
let token = word(bytes, at).ok_or(ShaderError::MissingEnd)?;
let opcode = token as u16;
if opcode == END {
let trailing = words - at - 1;
return if trailing == 0 {
Ok(Self { bytes, version })
} else {
Err(ShaderError::TrailingWords(trailing))
};
}
let operand_words = if opcode == COMMENT {
((token >> 16) & 0x7fff) as usize
} else {
((token >> 24) & 0x0f) as usize
};
let needed = operand_words + 1;
let have = words - at;
if have < needed {
return Err(ShaderError::Truncated {
at_word: at,
needed,
have,
});
}
at += needed;
}
}
pub const fn version(self) -> ShaderVersion {
self.version
}
pub const fn bytes(self) -> &'a [u8] {
self.bytes
}
pub const fn word_len(self) -> usize {
self.bytes.len() / 4
}
pub fn instructions(self) -> Instructions<'a> {
Instructions {
bytes: self.bytes,
at: 1,
done: false,
}
}
pub fn ctab(self) -> Result<Option<ConstantTable<'a>>, ShaderError> {
for instruction in self.instructions() {
let instruction = instruction?;
let Some(comment) = instruction.comment_data() else {
continue;
};
for offset in (0..comment.len()).step_by(4) {
if word(comment, offset / 4) == Some(CTAB) {
return ConstantTable::parse(&comment[offset + 4..]).map(Some);
}
}
}
Ok(None)
}
pub fn disassembly(self) -> Disassembly<'a> {
Disassembly { shader: self }
}
}
fn word(bytes: &[u8], index: usize) -> Option<u32> {
let at = index.checked_mul(4)?;
let bytes: [u8; 4] = bytes.get(at..at + 4)?.try_into().ok()?;
Some(u32::from_le_bytes(bytes))
}
#[derive(Clone, Copy, Debug)]
pub struct Instructions<'a> {
bytes: &'a [u8],
at: usize,
done: bool,
}
impl<'a> Iterator for Instructions<'a> {
type Item = Result<Instruction<'a>, ShaderError>;
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let token = word(self.bytes, self.at)?;
let opcode = token as u16;
if opcode == END {
self.done = true;
return Some(Ok(Instruction {
token,
operands: &[],
at_word: self.at,
}));
}
let count = if opcode == COMMENT {
((token >> 16) & 0x7fff) as usize
} else {
((token >> 24) & 0x0f) as usize
};
let next = match self.at.checked_add(count + 1) {
Some(next) => next,
None => {
return Some(Err(ShaderError::Truncated {
at_word: self.at,
needed: count + 1,
have: 0,
}));
}
};
let operands = match self.bytes.get((self.at + 1) * 4..next * 4) {
Some(operands) => operands,
None => {
return Some(Err(ShaderError::Truncated {
at_word: self.at,
needed: count + 1,
have: self.bytes.len() / 4 - self.at,
}));
}
};
let instruction = Instruction {
token,
operands,
at_word: self.at,
};
self.at = next;
Some(Ok(instruction))
}
}
#[derive(Clone, Copy, Debug)]
pub struct Instruction<'a> {
token: u32,
operands: &'a [u8],
at_word: usize,
}
impl<'a> Instruction<'a> {
pub const fn at_word(self) -> usize {
self.at_word
}
pub const fn opcode(self) -> Opcode {
Opcode(self.token as u16)
}
pub const fn raw_token(self) -> u32 {
self.token
}
pub const fn predicated(self) -> bool {
self.token & 0x1000_0000 != 0
}
pub const fn coissue(self) -> bool {
self.token & 0x4000_0000 != 0
}
pub const fn operand_len(self) -> usize {
self.operands.len() / 4
}
pub fn operand(self, index: usize) -> Option<u32> {
word(self.operands, index)
}
pub fn comment_data(self) -> Option<&'a [u8]> {
(self.opcode().0 == COMMENT).then_some(self.operands)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Opcode(u16);
impl Opcode {
pub const fn from_raw(raw: u16) -> Self {
Self(raw)
}
pub const fn raw(self) -> u16 {
self.0
}
pub const fn name(self) -> Option<&'static str> {
Some(match self.0 {
0x00 => "nop",
0x01 => "mov",
0x02 => "add",
0x03 => "sub",
0x04 => "mad",
0x05 => "mul",
0x06 => "rcp",
0x07 => "rsq",
0x08 => "dp3",
0x09 => "dp4",
0x0a => "min",
0x0b => "max",
0x0c => "slt",
0x0d => "sge",
0x0e => "exp",
0x0f => "log",
0x10 => "lit",
0x11 => "dst",
0x12 => "lrp",
0x13 => "frc",
0x14 => "m4x4",
0x15 => "m4x3",
0x16 => "m3x4",
0x17 => "m3x3",
0x18 => "m3x2",
0x19 => "call",
0x1a => "callnz",
0x1b => "loop",
0x1c => "ret",
0x1d => "endloop",
0x1e => "label",
0x1f => "dcl",
0x20 => "pow",
0x21 => "crs",
0x22 => "sgn",
0x23 => "abs",
0x24 => "nrm",
0x25 => "sincos",
0x26 => "rep",
0x27 => "endrep",
0x28 => "if",
0x29 => "ifc",
0x2a => "else",
0x2b => "endif",
0x2c => "break",
0x2d => "breakc",
0x2e => "mova",
0x2f => "defb",
0x30 => "defi",
0x40 => "texcoord",
0x41 => "texkill",
0x42 => "texld",
0x4e => "expp",
0x4f => "logp",
0x50 => "cnd",
0x51 => "def",
0x58 => "cmp",
0x59 => "bem",
0x5a => "dp2add",
0x5b => "dsx",
0x5c => "dsy",
0x5d => "texldd",
0x5e => "setp",
0x5f => "texldl",
0x60 => "breakp",
END => "end",
COMMENT => "comment",
_ => return None,
})
}
const fn source_only(self) -> bool {
matches!(
self.0,
0x19 | 0x1a | 0x1b | 0x1e | 0x28 | 0x29 | 0x2d | 0x26 | 0x60
)
}
}
#[derive(Clone, Copy, Debug)]
pub struct ConstantTable<'a> {
bytes: &'a [u8],
constant_count: u32,
constant_info_offset: u32,
}
impl<'a> ConstantTable<'a> {
fn parse(bytes: &'a [u8]) -> Result<Self, ShaderError> {
if bytes.len() < 28 || word(bytes, 0) != Some(28) {
return Err(ShaderError::MalformedCtab);
}
let constant_count = word(bytes, 3).ok_or(ShaderError::MalformedCtab)?;
let constant_info_offset = word(bytes, 4).ok_or(ShaderError::MalformedCtab)?;
let entries_end = (constant_info_offset as usize)
.checked_add((constant_count as usize).saturating_mul(20))
.ok_or(ShaderError::MalformedCtab)?;
if entries_end > bytes.len() {
return Err(ShaderError::MalformedCtab);
}
Ok(Self {
bytes,
constant_count,
constant_info_offset,
})
}
pub const fn len(self) -> usize {
self.constant_count as usize
}
pub const fn is_empty(self) -> bool {
self.constant_count == 0
}
pub fn constant(self, index: usize) -> Result<Constant<'a>, ShaderError> {
if index >= self.len() {
return Err(ShaderError::MalformedCtab);
}
let at = self.constant_info_offset as usize + index * 20;
let name_offset = word_at(self.bytes, at)?;
let register_set = u16_at(self.bytes, at + 4)?;
let register_index = u16_at(self.bytes, at + 6)?;
let register_count = u16_at(self.bytes, at + 8)?;
let name = c_string_at(self.bytes, name_offset as usize)?;
Ok(Constant {
name,
register_set,
register_index,
register_count,
})
}
pub fn register_name(
self,
register_set: u16,
register: u16,
) -> Result<Option<&'a [u8]>, ShaderError> {
for index in 0..self.len() {
let constant = self.constant(index)?;
if constant.register_set == register_set
&& register >= constant.register_index
&& register
< constant
.register_index
.saturating_add(constant.register_count)
{
return Ok(Some(constant.name));
}
}
Ok(None)
}
}
fn word_at(bytes: &[u8], at: usize) -> Result<u32, ShaderError> {
let bytes: [u8; 4] = bytes
.get(at..at + 4)
.ok_or(ShaderError::MalformedCtab)?
.try_into()
.map_err(|_| ShaderError::MalformedCtab)?;
Ok(u32::from_le_bytes(bytes))
}
fn u16_at(bytes: &[u8], at: usize) -> Result<u16, ShaderError> {
let bytes: [u8; 2] = bytes
.get(at..at + 2)
.ok_or(ShaderError::MalformedCtab)?
.try_into()
.map_err(|_| ShaderError::MalformedCtab)?;
Ok(u16::from_le_bytes(bytes))
}
fn c_string_at(bytes: &[u8], at: usize) -> Result<&[u8], ShaderError> {
let bytes = bytes.get(at..).ok_or(ShaderError::MalformedCtab)?;
let end = bytes
.iter()
.position(|&byte| byte == 0)
.ok_or(ShaderError::MalformedCtab)?;
Ok(&bytes[..end])
}
#[derive(Clone, Copy, Debug)]
pub struct Constant<'a> {
pub name: &'a [u8],
pub register_set: u16,
pub register_index: u16,
pub register_count: u16,
}
#[derive(Clone, Copy, Debug)]
pub struct Disassembly<'a> {
shader: Shader<'a>,
}
impl fmt::Display for Disassembly<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let version = self.shader.version();
let kind = match version.kind {
ShaderKind::Pixel => "ps",
ShaderKind::Vertex => "vs",
};
writeln!(f, "{kind}_{}_{}", version.major, version.minor)?;
let ctab = self.shader.ctab().map_err(|_| fmt::Error)?;
if let Some(ctab) = ctab {
writeln!(f, "; {} named constants/samplers", ctab.len())?;
} else {
writeln!(f, "; 0 named constants/samplers")?;
}
for instruction in self.shader.instructions() {
let instruction = instruction.map_err(|_| fmt::Error)?;
if instruction.comment_data().is_some() {
continue;
}
format_instruction(f, instruction, ctab)?;
}
Ok(())
}
}
fn format_instruction(
f: &mut fmt::Formatter<'_>,
instruction: Instruction<'_>,
ctab: Option<ConstantTable<'_>>,
) -> fmt::Result {
let opcode = instruction.opcode();
let name = opcode.name().unwrap_or("unknown");
if opcode.0 == END {
return writeln!(f, "end");
}
if opcode.0 == 0x51 && instruction.operand_len() == 5 {
write!(f, " def ")?;
format_register(f, instruction.operand(0).ok_or(fmt::Error)?, ctab, true)?;
for index in 1..5 {
let value = f32::from_bits(instruction.operand(index).ok_or(fmt::Error)?);
f.write_str(", ")?;
format_float_g6(f, value)?;
}
return writeln!(f);
}
if opcode.0 == 0x1f {
write!(f, " dcl ")?;
if instruction.operand_len() >= 2 {
format_register(f, instruction.operand(1).ok_or(fmt::Error)?, ctab, true)?;
return writeln!(
f,
" ; usage {:#x}",
instruction.operand(0).ok_or(fmt::Error)?
);
}
if instruction.operand_len() == 1 {
format_register(f, instruction.operand(0).ok_or(fmt::Error)?, ctab, true)?;
}
return writeln!(f);
}
let comparison = match (opcode.0, (instruction.token >> 16) & 7) {
(0x29 | 0x2d, 1) => "_gt",
(0x29 | 0x2d, 2) => "_eq",
(0x29 | 0x2d, 3) => "_ge",
(0x29 | 0x2d, 4) => "_lt",
(0x29 | 0x2d, 5) => "_ne",
(0x29 | 0x2d, 6) => "_le",
_ => "",
};
write!(f, " {name}{comparison}")?;
let has_destination = !opcode.source_only() && instruction.operand_len() > 0;
if has_destination {
let dest = instruction.operand(0).ok_or(fmt::Error)?;
format_destination_modifiers(f, dest)?;
write!(f, " ")?;
format_register(f, dest, ctab, true)?;
}
let start = usize::from(has_destination);
if !has_destination && instruction.operand_len() > 0 {
write!(f, " ")?;
} else if has_destination && instruction.operand_len() > start {
write!(f, ", ")?;
}
for index in start..instruction.operand_len() {
if index > start {
write!(f, ", ")?;
}
let operand = instruction.operand(index).ok_or(fmt::Error)?;
format_source(f, operand, ctab)?;
}
writeln!(f)
}
fn format_destination_modifiers(f: &mut fmt::Formatter<'_>, token: u32) -> fmt::Result {
let modifiers = (token >> 20) & 0x0f;
if modifiers & 1 != 0 {
f.write_str("_sat")?;
}
if modifiers & 2 != 0 {
f.write_str("_pp")?;
}
if modifiers & 4 != 0 {
f.write_str("_centroid")?;
}
Ok(())
}
fn format_register(
f: &mut fmt::Formatter<'_>,
token: u32,
ctab: Option<ConstantTable<'_>>,
destination: bool,
) -> fmt::Result {
let register = (token & 0x7ff) as u16;
let register_type = (((token & 0x7000_0000) >> 28) | ((token & 0x0000_1800) >> 8)) as u16;
let name = match register_type {
0 => "r",
1 => "v",
2 | 11 | 12 | 13 => "c",
3 => "t",
4 => "oPos",
5 => "oD",
6 => "o",
7 => "i",
8 => "oC",
9 => "oDepth",
10 => "s",
14 => "b",
15 => "aL",
16 => "rf16",
17 => "misc",
18 => "label",
19 => "p",
_ => "?",
};
let no_number = matches!(register_type, 4 | 9 | 15);
write!(f, "{name}")?;
if !no_number {
write!(f, "{register}")?;
}
let ctab_set = match name {
"c" => Some(2),
"s" => Some(3),
"b" => Some(0),
"i" => Some(1),
_ => None,
};
if let (Some(ctab), Some(set)) = (ctab, ctab_set)
&& let Ok(Some(constant)) = ctab.register_name(set, register)
&& let Ok(constant) = core::str::from_utf8(constant)
{
write!(f, "[{constant}]")?;
}
if destination {
let mask = (token >> 16) & 0x0f;
if mask != 0x0f {
f.write_str(".")?;
for (bit, component) in [(1, 'x'), (2, 'y'), (4, 'z'), (8, 'w')] {
if mask & bit != 0 {
write!(f, "{component}")?;
}
}
}
} else {
let swizzle = (token >> 16) & 0xff;
if swizzle != 0xe4 {
let components = ['x', 'y', 'z', 'w'];
let first = components[(swizzle & 3) as usize];
let splat = (1..4).all(|index| ((swizzle >> (index * 2)) & 3) == (swizzle & 3));
write!(f, ".{first}")?;
if !splat {
for index in 1..4 {
write!(f, "{}", components[((swizzle >> (index * 2)) & 3) as usize])?;
}
}
}
}
Ok(())
}
fn format_source(
f: &mut fmt::Formatter<'_>,
token: u32,
ctab: Option<ConstantTable<'_>>,
) -> fmt::Result {
match (token >> 24) & 0x0f {
0 => format_register(f, token, ctab, false),
1 => {
f.write_str("-")?;
format_register(f, token, ctab, false)
}
3 => {
f.write_str("|")?;
format_register(f, token, ctab, false)?;
f.write_str("|")
}
4 => {
f.write_str("-|")?;
format_register(f, token, ctab, false)?;
f.write_str("|")
}
_ => format_register(f, token, ctab, false),
}
}
fn format_float_g6(f: &mut fmt::Formatter<'_>, value: f32) -> fmt::Result {
if value == 0.0 {
return f.write_str("0");
}
if !value.is_finite() {
return write!(f, "{value}");
}
let negative = value.is_sign_negative();
let absolute = value.abs();
let mut precision = 0usize;
if absolute >= 1.0 {
let mut whole = absolute as u64;
let mut digits = 1usize;
while whole >= 10 {
whole /= 10;
digits += 1;
}
precision = 6usize.saturating_sub(digits);
} else {
let mut scaled = absolute;
while scaled < 1.0 {
scaled *= 10.0;
precision += 1;
}
precision += 5;
}
let mut scale = 1u64;
for _ in 0..precision {
scale = scale.saturating_mul(10);
}
let mut rounded = (absolute * scale as f32 + 0.5) as u64;
while precision > 0 && rounded.is_multiple_of(10) {
rounded /= 10;
scale /= 10;
precision -= 1;
}
if negative {
f.write_str("-")?;
}
if precision == 0 {
return write!(f, "{rounded}");
}
if rounded < scale {
f.write_str("0.")?;
let mut padding = scale / 10;
while padding > rounded && padding > 1 {
f.write_str("0")?;
padding /= 10;
}
return write!(f, "{rounded}");
}
write!(f, "{}.", rounded / scale)?;
let fraction = rounded % scale;
let mut padding = scale / 10;
while padding > fraction && padding > 1 {
f.write_str("0")?;
padding /= 10;
}
write!(f, "{fraction}")
}
+4 -2
View File
@@ -1,4 +1,6 @@
use crate::{AssetType, Ptr, XFILE_BLOCK_VIRTUAL, XFILE_HEADER_LEN, parse_zone_header};
use crate::{
AssetType, MAX_XFILE_COUNT, Ptr, XFILE_BLOCK_VIRTUAL, XFILE_HEADER_LEN, parse_zone_header,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Iw4WireFormat {
@@ -38,7 +40,7 @@ impl WirePointer {
} else {
let packed = u32::try_from(raw.checked_sub(1)?).ok()?;
let block = (packed >> 28) as u8;
(block < 8).then_some(Self::Offset(Ptr {
((block as usize) < MAX_XFILE_COUNT).then_some(Self::Offset(Ptr {
block,
offset: packed & 0x0fff_ffff,
}))
-1
View File
@@ -23,7 +23,6 @@ net = { path = "../net" }
sim = { path = "../sim" }
math_iw4.workspace = true
gamemode_iw4.workspace = true
killcam_iw4 = { path = "../killcam_iw4" }
[lints]
workspace = true
-1
View File
@@ -17,7 +17,6 @@ rustls = { version = "0.23.31", default-features = false, features = ["ring", "s
rustls-pemfile = "2.2.0"
rustls-platform-verifier = "0.7.0"
tokio = { version = "1.47", features = ["macros", "rt-multi-thread", "sync", "time"] }
tokio-util = { version = "0.7", default-features = false, features = ["rt"] }
[lints]
workspace = true
-1
View File
@@ -16,7 +16,6 @@ bevy-trace = ["bootstrap/bevy-trace"]
[dependencies]
diag.workspace = true
asset_transport.workspace = true
assets.workspace = true
bootstrap = { path = "../bootstrap" }
[lints]
-21
View File
@@ -8,40 +8,19 @@ description = "Snapshot to pixels: scene, viewmodel, effects. No game logic."
[dependencies]
diag.workspace = true
bevy.workspace = true
anim_iw4.workspace = true
asset_iw4.workspace = true
d3d9_sm3.workspace = true
d3d9_state.workspace = true
dpvs_iw4.workspace = true
entity_iw4.workspace = true
fx.workspace = true
fx_iw4.workspace = true
marks_iw4.workspace = true
gamemode_iw4.workspace = true
fastfile_iw4.workspace = true
lighting_iw4.workspace = true
math_iw4.workspace = true
playerstate_iw4.workspace = true
weapon_iw4.workspace = true
hud_iw4.workspace = true
hud = { path = "../hud" }
frame.workspace = true
render_frame.workspace = true
render_anim.workspace = true
render_frontend.workspace = true
render_backend.workspace = true
render_fx.workspace = true
render_gpu.workspace = true
render_scene.workspace = true
net = { path = "../net" }
assets.workspace = true
asset_world.workspace = true
audio.workspace = true
sim.workspace = true
serde.workspace = true
serde_json.workspace = true
miniz_oxide.workspace = true
bytemuck = { version = "1", features = ["derive"] }
naga = { version = "29", features = ["wgsl-in"] }
perf.workspace = true
-1
View File
@@ -24,7 +24,6 @@ frame.workspace = true
fx.workspace = true
fx_iw4.workspace = true
hud_iw4.workspace = true
gamemode_iw4.workspace = true
lighting_iw4.workspace = true
math_iw4.workspace = true
net.workspace = true
+2 -31
View File
@@ -2,25 +2,6 @@ use asset_game::WeaponAnimSlot;
use crate::{EventResult, ViewmodelController, ViewmodelEvent, WeaponState};
pub mod auth_ws {
pub const READY: i32 = 0x0;
pub const RAISING: i32 = 0x1;
pub const RAISING_ALTSWITCH: i32 = 0x2;
pub const DROPPING: i32 = 0x3;
pub const DROPPING_QUICK: i32 = 0x4;
pub const DROPPING_ALTSWITCH: i32 = 0x5;
pub const FIRING: i32 = 0x6;
pub const RECHAMBERING: i32 = 0x7;
pub const RELOADING: i32 = 0x8;
pub const RELOADING_INTERRUPT: i32 = 0x9;
pub const RELOAD_START: i32 = 0xA;
pub const RELOAD_START_INTERRUPT: i32 = 0xB;
pub const RELOAD_END: i32 = 0xC;
pub const SPRINT_IN: i32 = 0x17;
pub const SPRINT_LOOP: i32 = 0x18;
pub const SPRINT_OUT: i32 = 0x19;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PresentFpvEvent {
Fire,
@@ -56,11 +37,7 @@ pub struct FpvPoseSample {
pub idle_weight: f32,
}
pub fn map_authority_to_fpv(
_prev_weaponstate: Option<i32>,
_weaponstate: i32,
cues: AuthorityFpvCues,
) -> Vec<PresentFpvEvent> {
pub fn map_authority_to_fpv(cues: AuthorityFpvCues) -> Vec<PresentFpvEvent> {
let mut out = Vec::new();
if cues.shot_accepted {
@@ -248,8 +225,6 @@ pub enum WeapAnimEdge {
#[derive(Clone, Debug, Default)]
pub struct FpvPresentState {
pub last_tick: Option<u32>,
pub last_weaponstate: Option<i32>,
pub last_sprinting: Option<bool>,
pub last_ads_frac: Option<f32>,
@@ -263,8 +238,6 @@ pub struct FpvPresentState {
impl FpvPresentState {
pub fn clear(&mut self) {
self.last_tick = None;
self.last_weaponstate = None;
self.last_sprinting = None;
self.last_ads_frac = None;
self.last_weap_anim = None;
self.last_weap_anim_secondary = None;
@@ -326,10 +299,8 @@ pub fn events_for_authority_tick(
if present.last_tick == Some(sample.tick) {
return Vec::new();
}
let events = map_authority_to_fpv(present.last_weaponstate, sample.weaponstate, sample.cues);
let events = map_authority_to_fpv(sample.cues);
present.last_tick = Some(sample.tick);
present.last_weaponstate = Some(sample.weaponstate);
present.last_sprinting = Some(sample.sprinting);
present.last_ads_frac = Some(sample.ads_frac);
events
}
-4
View File
@@ -19,24 +19,20 @@ xmodel_runtime.workspace = true
anim_iw4.workspace = true
audio.workspace = true
bevy.workspace = true
d3d9_decl.workspace = true
d3d9_sm3.workspace = true
d3d9_state.workspace = true
diag.workspace = true
dpvs_iw4.workspace = true
entity_iw4.workspace = true
fastfile_iw4.workspace = true
frame.workspace = true
fx.workspace = true
fx_iw4.workspace = true
gamemode_iw4.workspace = true
lighting_iw4.workspace = true
hud_iw4.workspace = true
marks_iw4.workspace = true
math_iw4.workspace = true
net.workspace = true
perf.workspace = true
playerstate_iw4.workspace = true
render_anim.workspace = true
render_frame.workspace = true
render_fx.workspace = true
@@ -1,336 +0,0 @@
use super::gpu_contract::WgpuPassLayout;
use super::material_runtime::{
ExecutablePassView, PackedCodeConstantLane, PackedLocalBanks, PortId, RuntimeProgramPort,
RuntimeShaderStage,
};
use super::sm3_abi::{ConstantBinding, ConstantSource};
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PassConstantBuffers {
pub vertex: Vec<[u32; 4]>,
pub pixel: Vec<[u32; 4]>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ConstantPackRefusal {
ExecutablePairMismatch,
MissingLocalBanks,
DestinationPastConstantBlock {
stage: RuntimeShaderStage,
destination: u16,
block_len: usize,
},
MissingConstantRegister {
stage: RuntimeShaderStage,
register: u16,
source: ConstantSource,
},
}
impl RuntimeProgramPort {
pub fn pack_hit(
&self,
pass: ExecutablePassView<'_>,
) -> Result<PassConstantBuffers, ConstantPackRefusal> {
let Some(seed) = pass.local_banks.map(Arc::as_ref) else {
return Err(ConstantPackRefusal::MissingLocalBanks);
};
if seed.vertex.len() == self.module().vertex_constant_len
&& seed.pixel.len() == self.module().pixel_constant_len
&& seed.written_vertex.len() == seed.vertex.len()
&& seed.written_pixel.len() == seed.pixel.len()
{
return pack_code_on_seed(
self.id(),
&self.abi().vertex_constants,
&self.abi().pixel_constants,
seed,
pass,
);
}
Err(ConstantPackRefusal::DestinationPastConstantBlock {
stage: RuntimeShaderStage::Vertex,
destination: 0,
block_len: seed.vertex.len(),
})
}
pub fn pack_hit_into(
&self,
pass: ExecutablePassView<'_>,
overlay: &[PackedCodeConstantLane],
out: &mut Vec<u8>,
) -> Result<(), ConstantPackRefusal> {
let Some(seed) = pass.local_banks.map(Arc::as_ref) else {
return Err(ConstantPackRefusal::MissingLocalBanks);
};
let module = self.module();
if seed.vertex.len() != module.vertex_constant_len
|| seed.pixel.len() != module.pixel_constant_len
|| seed.written_vertex.len() != seed.vertex.len()
|| seed.written_pixel.len() != seed.pixel.len()
{
return Err(ConstantPackRefusal::DestinationPastConstantBlock {
stage: RuntimeShaderStage::Vertex,
destination: 0,
block_len: seed.vertex.len(),
});
}
if !self.accepts_pass(pass) {
return Err(ConstantPackRefusal::ExecutablePairMismatch);
}
require_abi_rows_with_lanes(
RuntimeShaderStage::Vertex,
&self.abi().vertex_constants,
&seed.written_vertex,
pass.code_constants,
)?;
require_abi_rows_with_lanes(
RuntimeShaderStage::Pixel,
&self.abi().pixel_constants,
&seed.written_pixel,
pass.code_constants,
)?;
let start = out.len();
out.extend_from_slice(bytemuck::cast_slice(seed.vertex.as_slice()));
out.extend_from_slice(bytemuck::cast_slice(seed.pixel.as_slice()));
let result = pass
.code_constants
.iter()
.chain(overlay)
.try_for_each(|lane| {
overlay_lane_bytes(lane, &mut out[start..], seed.vertex.len(), seed.pixel.len())
});
if result.is_err() {
out.truncate(start);
}
result
}
}
fn overlay_lane_bytes(
lane: &PackedCodeConstantLane,
span: &mut [u8],
vertex_len: usize,
pixel_len: usize,
) -> Result<(), ConstantPackRefusal> {
let (bank_off, bank_len) = match lane.stage {
RuntimeShaderStage::Vertex => (0usize, vertex_len),
RuntimeShaderStage::Pixel => (vertex_len, pixel_len),
};
let first = usize::from(lane.first_row);
let rows = &lane.rows[first..first.saturating_add(usize::from(lane.row_count))];
for (row, words) in rows.iter().enumerate() {
let register = usize::from(lane.destination).saturating_add(row);
if register >= bank_len {
return Err(ConstantPackRefusal::DestinationPastConstantBlock {
stage: lane.stage,
destination: u16::try_from(register).unwrap_or(u16::MAX),
block_len: bank_len,
});
}
let at = (bank_off + register) * 16;
span[at..at + 16].copy_from_slice(bytemuck::bytes_of(words));
}
Ok(())
}
fn require_abi_rows_with_lanes(
stage: RuntimeShaderStage,
bindings: &[ConstantBinding],
seed_written: &[bool],
lanes: &[PackedCodeConstantLane],
) -> Result<(), ConstantPackRefusal> {
let mut covered = [0u64; 4];
for lane in lanes.iter().filter(|lane| lane.stage == stage) {
let first = usize::from(lane.destination);
for register in first..first.saturating_add(usize::from(lane.row_count)).min(256) {
covered[register / 64] |= 1u64 << (register % 64);
}
}
for binding in bindings {
if binding.source == ConstantSource::ProgramDefined {
continue;
}
let index = usize::from(binding.register);
if index >= seed_written.len() || seed_written[index] {
continue;
}
if index >= 256 || covered[index / 64] & (1u64 << (index % 64)) == 0 {
return Err(ConstantPackRefusal::MissingConstantRegister {
stage,
register: binding.register,
source: binding.source,
});
}
}
Ok(())
}
fn pack_code_on_seed(
expected_port: PortId,
vertex_constants: &[ConstantBinding],
pixel_constants: &[ConstantBinding],
seed: &PackedLocalBanks,
pass: ExecutablePassView<'_>,
) -> Result<PassConstantBuffers, ConstantPackRefusal> {
if pass.port != expected_port || !expected_port.matches_shader_pair(pass.shader_pair) {
return Err(ConstantPackRefusal::ExecutablePairMismatch);
}
let mut vertex = seed.vertex.clone();
let mut pixel = seed.pixel.clone();
let mut written_vertex = seed.written_vertex.clone();
let mut written_pixel = seed.written_pixel.clone();
for lane in pass.code_constants {
let start = usize::from(lane.first_row);
let end = start.saturating_add(usize::from(lane.row_count));
write_rows(
lane.stage,
lane.destination,
&lane.rows[start..end],
&mut vertex,
&mut pixel,
&mut written_vertex,
&mut written_pixel,
)?;
}
require_abi_rows(
RuntimeShaderStage::Vertex,
vertex_constants,
&written_vertex,
)?;
require_abi_rows(RuntimeShaderStage::Pixel, pixel_constants, &written_pixel)?;
Ok(PassConstantBuffers { vertex, pixel })
}
pub fn overlay_packed_code_on_banks(
vertex: &mut [[u32; 4]],
pixel: &mut [[u32; 4]],
lanes: &[PackedCodeConstantLane],
) -> Result<u32, ConstantPackRefusal> {
let mut written = 0u32;
for lane in lanes {
let start = usize::from(lane.first_row);
let end = start.saturating_add(usize::from(lane.row_count));
overlay_write_rows(
lane.stage,
lane.destination,
&lane.rows[start..end],
vertex,
pixel,
)?;
written = written.saturating_add(u32::from(lane.row_count));
}
Ok(written)
}
fn overlay_write_rows(
stage: RuntimeShaderStage,
destination: u16,
rows: &[[u32; 4]],
vertex: &mut [[u32; 4]],
pixel: &mut [[u32; 4]],
) -> Result<(), ConstantPackRefusal> {
let bank = match stage {
RuntimeShaderStage::Vertex => &mut *vertex,
RuntimeShaderStage::Pixel => &mut *pixel,
};
for (row, words) in rows.iter().enumerate() {
let register = destination
.checked_add(u16::try_from(row).expect("row index fits u16"))
.ok_or(ConstantPackRefusal::DestinationPastConstantBlock {
stage,
destination,
block_len: bank.len(),
})?;
let index = usize::from(register);
if index >= bank.len() {
return Err(ConstantPackRefusal::DestinationPastConstantBlock {
stage,
destination: register,
block_len: bank.len(),
});
}
bank[index] = *words;
}
Ok(())
}
fn write_rows(
stage: RuntimeShaderStage,
destination: u16,
rows: &[[u32; 4]],
vertex: &mut [[u32; 4]],
pixel: &mut [[u32; 4]],
written_vertex: &mut [bool],
written_pixel: &mut [bool],
) -> Result<(), ConstantPackRefusal> {
let (bank, written) = match stage {
RuntimeShaderStage::Vertex => (&mut *vertex, &mut *written_vertex),
RuntimeShaderStage::Pixel => (&mut *pixel, &mut *written_pixel),
};
for (row, words) in rows.iter().enumerate() {
let register = destination
.checked_add(u16::try_from(row).expect("row index fits u16"))
.ok_or(ConstantPackRefusal::DestinationPastConstantBlock {
stage,
destination,
block_len: bank.len(),
})?;
let index = usize::from(register);
if index >= bank.len() {
return Err(ConstantPackRefusal::DestinationPastConstantBlock {
stage,
destination: register,
block_len: bank.len(),
});
}
bank[index] = *words;
written[index] = true;
}
Ok(())
}
fn require_abi_rows(
stage: RuntimeShaderStage,
bindings: &[ConstantBinding],
written: &[bool],
) -> Result<(), ConstantPackRefusal> {
for binding in bindings {
if binding.source == ConstantSource::ProgramDefined {
continue;
}
let index = usize::from(binding.register);
if index >= written.len() {
continue;
}
if !written[index] {
return Err(ConstantPackRefusal::MissingConstantRegister {
stage,
register: binding.register,
source: binding.source,
});
}
}
Ok(())
}
pub fn split_bind_layout(
layout: &WgpuPassLayout,
) -> (
Vec<super::WgpuBindLayoutEntry>,
Vec<super::WgpuBindLayoutEntry>,
) {
let mut constants = Vec::new();
let mut textures = Vec::new();
for entry in &layout.bind_entries {
match entry.group {
0 => constants.push(*entry),
1 => textures.push(*entry),
_ => {}
}
}
(constants, textures)
}
@@ -6,7 +6,6 @@ pub mod film_vision_view;
pub mod fog;
pub mod frame_products;
pub mod gpu_contract;
pub mod gpu_prepare;
pub mod image_handles;
pub(crate) mod list;
pub mod lit_draw_method;
@@ -21,7 +20,6 @@ pub mod setup;
pub mod sm3;
pub mod sm3_abi;
pub mod sm3_wgsl;
pub mod smodel_cached;
pub mod spot_shadow_casters;
pub mod state;
pub mod sun_effects;
@@ -36,7 +34,6 @@ pub use depth_range::*;
pub use film_vision_view::*;
pub use frame_products::*;
pub use gpu_contract::*;
pub use gpu_prepare::*;
pub use image_handles::*;
pub use list::*;
pub use lit_draw_method::*;
@@ -51,7 +48,6 @@ pub use setup::*;
pub use sm3::*;
pub use sm3_abi::*;
pub use sm3_wgsl::*;
pub use smodel_cached::*;
pub use spot_shadow_casters::*;
pub use state::*;
pub use sun_effects::SunEffectsFrameInput;
@@ -1,80 +0,0 @@
use asset_iw4::vertex_decl as vd;
use bevy::mesh::VertexBufferLayout;
use bevy::render::render_resource::{VertexAttribute, VertexFormat, VertexStepMode};
use super::sm3_abi::PassProgramAbi;
pub const SMODEL_PRETESS_VERTEX: usize = asset_iw4::size::GFX_PACKED_VERTEX + 16;
pub fn cached_lighting_location(abi: &PassProgramAbi) -> Option<u32> {
let max = abi
.vertex_inputs
.iter()
.map(|input| input.attribute.map(|attribute| attribute.location))
.max()??;
max.checked_add(1)
}
pub fn lighting_texcoord_register(abi: &PassProgramAbi) -> Option<String> {
abi.varyings.iter().find_map(|varying| {
if varying.semantic.usage == vd::D3DDECLUSAGE_TEXCOORD && varying.semantic.usage_index == 6
{
Some(format!("o{}", varying.vertex_register.index))
} else {
None
}
})
}
pub fn cached_lighting_vertex_buffers(
packed: &[VertexBufferLayout],
location: u32,
) -> Vec<VertexBufferLayout> {
packed
.iter()
.map(|buffer| {
let mut attributes = buffer.attributes.to_vec();
attributes.push(VertexAttribute {
format: VertexFormat::Float32x4,
offset: asset_iw4::size::GFX_PACKED_VERTEX as u64,
shader_location: location,
});
VertexBufferLayout {
array_stride: SMODEL_PRETESS_VERTEX as u64,
step_mode: VertexStepMode::Vertex,
attributes: attributes.into(),
}
})
.collect()
}
pub fn inject_cached_lighting_attribute(
source: &str,
location: u32,
lighting_register: Option<&str>,
) -> Option<String> {
const SIG_END: &str = ") -> Sm3Varyings {";
let start = source.find("@vertex")?;
let sig = source[start..].find(SIG_END)? + start;
let mut out = String::with_capacity(source.len() + 160);
out.push_str(&source[..sig]);
out.push_str(&format!(
" @location({location}) attribute_{location}: vec4<f32>,\n"
));
out.push_str(SIG_END);
let after_sig = sig + SIG_END.len();
out.push_str(&format!(
"\n let lighting_coords = attribute_{location};\n"
));
if let Some(register) = lighting_register {
const RET: &str = " return Sm3Varyings(";
let rel = source[after_sig..].find(RET)?;
let at = after_sig + rel;
out.push_str(&source[after_sig..at]);
out.push_str(&format!(" {register} = lighting_coords;\n"));
out.push_str(&source[at..]);
} else {
out.push_str(&source[after_sig..]);
}
Some(out)
}
-1
View File
@@ -12,7 +12,6 @@ asset_material.workspace = true
asset_world.workspace = true
assets.workspace = true
bytemuck = { version = "1", features = ["derive"] }
d3d9_decl.workspace = true
d3d9_sm3.workspace = true
d3d9_state.workspace = true
diag.workspace = true
-1
View File
@@ -12,7 +12,6 @@ frame.workspace = true
net.workspace = true
sim.workspace = true
playerstate_iw4.workspace = true
movement_iw4.workspace = true
perf.workspace = true
getrandom = "0.3"
-2
View File
@@ -19,7 +19,6 @@ asset_world.workspace = true
assets.workspace = true
audio.workspace = true
net.workspace = true
render.workspace = true
render_frontend.workspace = true
render_fx.workspace = true
sim.workspace = true
@@ -28,7 +27,6 @@ clipmap_iw4.workspace = true
weapon_iw4.workspace = true
xmodel_runtime.workspace = true
hud_iw4.workspace = true
bots.workspace = true
perf.workspace = true
[lints]
+2 -24
View File
@@ -241,20 +241,6 @@ fn hash_equipment(h: &mut Digest, rows: &[crate::EquipmentRuntimeFacts]) {
}
}
pub fn content_digest_v1(
combat: &[WeaponCombatFacts],
bootstrap: &MatchBootstrap,
clip_brushes: &[SimBrush],
) -> u64 {
let mut h = Digest::new();
h.u64(CONTENT_DIGEST_SCHEME);
hash_combat(&mut h, combat);
hash_class_catalog(&mut h);
hash_spawns(&mut h, &bootstrap.spawns);
hash_collision(&mut h, clip_brushes);
h.finish()
}
fn hash_script_models(h: &mut Digest, script_models: &[crate::EntityCollisionCapabilities]) {
h.u32(script_models.len() as u32);
for capabilities in script_models {
@@ -300,7 +286,7 @@ fn hash_script_models(h: &mut Digest, script_models: &[crate::EntityCollisionCap
}
}
pub fn content_digest_v2(
pub fn content_digest(
combat: &[WeaponCombatFacts],
runnable: &[bool],
transition_groups: &[u32],
@@ -332,7 +318,7 @@ pub struct ContentComponents {
pub classes: u64,
}
pub fn content_components_v2(
pub fn content_components(
combat: &[WeaponCombatFacts],
runnable: &[bool],
transition_groups: &[u32],
@@ -370,11 +356,3 @@ pub fn content_components_v2(
classes: classes.finish(),
}
}
pub fn content_digest_v0(combat: &[WeaponCombatFacts], classes: &[ClassDef]) -> u64 {
let bootstrap = MatchBootstrap {
classes: classes.to_vec(),
..MatchBootstrap::default()
};
content_digest_v1(combat, &bootstrap, &[])
}
+1 -4
View File
@@ -60,10 +60,7 @@ pub use combat::{
AcceptedShot, Emission, EntityClipKind, PlayerCollisionRepresentation, ShotCollisionGeometry,
ShotCollisionVerdict, TracePhaseOutput, spread_direction_on_plane, spread_pellet_direction,
};
pub use content::{
CONTENT_DIGEST_SCHEME, ContentComponents, content_components_v2, content_digest_v0,
content_digest_v1, content_digest_v2,
};
pub use content::{CONTENT_DIGEST_SCHEME, ContentComponents, content_components, content_digest};
pub use corpse::{PlayerCorpsePool, PlayerCorpseSlot, level_time_ms};
pub use damage::{DamageAttempt, DamageOutcome, DamageRefusal, DeathCommit};
pub use equipment::{
+2 -2
View File
@@ -1247,7 +1247,7 @@ impl SimState {
}
fn recompute_content_digest(&mut self) {
self.content_digest = crate::content::content_digest_v2(
self.content_digest = crate::content::content_digest(
&self.content.data.weapon_combat,
&self.content.data.weapon_runnable,
&self.content.data.weapon_transition_groups,
@@ -1256,7 +1256,7 @@ impl SimState {
&self.content.data.clip_brushes,
&self.entity_collision_capabilities,
);
self.content_components = crate::content::content_components_v2(
self.content_components = crate::content::content_components(
&self.content.data.weapon_combat,
&self.content.data.weapon_runnable,
&self.content.data.weapon_transition_groups,
-1
View File
@@ -15,7 +15,6 @@ asset_transport.workspace = true
assets.workspace = true
frame.workspace = true
net = { path = "../net" }
session.workspace = true
sim.workspace = true
[lints]