pub mod ps;
pub mod xbox;
use core::{error::Error, fmt};
#[derive(Debug, Clone, Copy)]
pub enum TextureSlice {
Source,
Dest,
}
#[derive(Debug, Clone, Copy)]
pub enum SwizzleError {
FormatOutOfRange(u32),
OutOfBounds(TextureSlice),
}
impl Error for SwizzleError {}
impl fmt::Display for SwizzleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SwizzleError::OutOfBounds(s) => write!(f, "slice {s:?} out of bounds"),
SwizzleError::FormatOutOfRange(e) => write!(f, "format is out of range ({e})"),
}
}
}
pub trait Swizzler {
fn swizzle<T: Format>(
source: &mut [u8],
dest: &mut [u8],
dimensions: (usize, usize, usize),
format: T,
align_resolution: bool,
) -> Result<(), SwizzleError>;
}
pub trait Deswizzler {
fn deswizzle<T: Format>(
source: &mut [u8],
dest: &mut [u8],
dimensions: (usize, usize, usize),
format: T,
align_resolution: bool,
) -> Result<(), SwizzleError>;
}
pub trait Format {
fn bpp(&self) -> usize;
fn block_size(&self) -> usize;
fn pixel_block_size(&self) -> usize;
fn is_compressed(&self) -> bool;
fn x360_swap(&self) -> bool;
}
pub fn morton(t: usize, x: usize, y: usize) -> usize {
let mut bit_position_x = 1;
let mut bit_position_y = 1;
let mut morton_code = t;
let mut mask_x = x;
let mut mask_y = y;
let mut result_x = 0;
let mut result_y = 0;
while mask_x > 1 || mask_y > 1 {
if mask_x > 1 {
result_x += bit_position_x * (morton_code & 1);
morton_code >>= 1;
bit_position_x <<= 1;
mask_x >>= 1;
}
if mask_y > 1 {
result_y += bit_position_y * (morton_code & 1);
morton_code >>= 1;
bit_position_y <<= 1;
mask_y >>= 1;
}
}
result_y * x + result_x
}