use rocketsplash_formats::Rgb;
use crate::RenderBuffer;
pub fn apply_shadow(buffer: &mut RenderBuffer, dx: i8, dy: i8, color: Rgb) {
if dx == 0 && dy == 0 {
return;
}
let width = buffer.width as i64;
let height = buffer.height as i64;
let mut shadows = Vec::new();
for y in 0..buffer.height {
for x in 0..buffer.width {
let idx = y * buffer.width + x;
let cell = buffer.cells[idx];
if cell.opacity == 0 {
continue;
}
let target_x = x as i64 + dx as i64;
let target_y = y as i64 + dy as i64;
if target_x < 0 || target_y < 0 || target_x >= width || target_y >= height {
continue;
}
let target_idx = target_y as usize * buffer.width + target_x as usize;
if !buffer.cells[target_idx].is_empty() {
continue;
}
let alpha = cell.opacity as f32 / 255.0;
let shadow_color = scale_color(color, alpha);
shadows.push((target_idx, cell.ch, Some(shadow_color), cell.opacity));
}
}
for (target_idx, ch, fg, opacity) in shadows {
if buffer.cells[target_idx].is_empty() {
let shadow_cell = &mut buffer.cells[target_idx];
shadow_cell.ch = ch;
shadow_cell.fg = fg;
shadow_cell.opacity = opacity;
}
}
}
fn scale_color(color: Rgb, alpha: f32) -> Rgb {
let clamp_alpha = alpha.clamp(0.0, 1.0);
Rgb {
r: (color.r as f32 * clamp_alpha).round() as u8,
g: (color.g as f32 * clamp_alpha).round() as u8,
b: (color.b as f32 * clamp_alpha).round() as u8,
}
}