#![deny(
clippy::arithmetic_side_effects,
clippy::indexing_slicing,
clippy::cast_possible_truncation
)]
#![deny(missing_docs)]
#![deny(clippy::disallowed_methods, clippy::disallowed_types)]
mod ctab;
mod debug;
mod disasm;
mod opcodes;
mod program;
pub use ctab::{Constant, ConstantTable, Type, TypeMember};
pub use debug::{DebugInfo, Location, SourceLine, Variable};
pub use disasm::{Options, disassemble, disassemble_with};
pub use opcodes::Opcode;
pub use program::{
Comment, Comparison, Declaration, Declared, Definition, Destination, Instruction, Item, Literal,
Modifier, Program, Records, Register, RegisterType, Relative, Source, TextureType, frame, read, records,
};
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
#[error("D3D9 at word {word}: {detail}")]
pub struct Error {
pub word: usize,
pub detail: String,
}
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) fn error(word: usize, detail: impl Into<String>) -> Error {
Error {
word,
detail: detail.into(),
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Stage {
Vertex,
Pixel,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Version {
pub stage: Stage,
pub major: u8,
pub minor: u8,
}
impl Version {
pub fn from_token(token: u32) -> Option<Self> {
let [minor, major, ..] = token.to_le_bytes();
let stage = match token >> 16 {
0xfffe => Stage::Vertex,
0xffff => Stage::Pixel,
_ => return None,
};
let known = matches!(
(stage, major, minor),
(Stage::Vertex, 1, 0 | 1) | (Stage::Pixel, 1, 0..=4) | (_, 2, 0 | 1 | 255) | (_, 3, 0 | 255)
);
known.then_some(Self { stage, major, minor })
}
pub fn token(self) -> u32 {
let stage: u32 = match self.stage {
Stage::Vertex => 0xfffe,
Stage::Pixel => 0xffff,
};
(stage << 16) | (u32::from(self.major) << 8) | u32::from(self.minor)
}
}
impl std::fmt::Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let stage = match self.stage {
Stage::Vertex => "vs",
Stage::Pixel => "ps",
};
match (self.major, self.minor) {
(2, 1) => write!(f, "{stage}_2_x"),
(major, 255) => write!(f, "{stage}_{major}_sw"),
(major, minor) => write!(f, "{stage}_{major}_{minor}"),
}
}
}