use std::cell::RefCell;
use std::rc::Rc;
use super::Rom;
use super::battle_background::BattleBackground;
use crate::rom::background_graphics::BackgroundGraphics;
use crate::rom::distorter::Distorter;
use crate::rom::distortion_effect::DistortionEffect;
use crate::rom::palette_cycle::PaletteCycle;
const WIDTH: usize = 256;
const HEIGHT: usize = 256;
#[derive(Debug)]
pub struct BackgroundLayer {
rom: Rc<RefCell<Rom>>,
graphics: Option<Rc<RefCell<BackgroundGraphics>>>,
palette_cycle: Option<PaletteCycle>,
pixels: Rc<RefCell<Vec<i16>>>,
distorter: Distorter,
pub entry: usize,
}
impl BackgroundLayer {
pub fn new(entry: usize, rom: Rc<RefCell<Rom>>) -> Self {
let pixels = Rc::new(RefCell::new(vec![0i16; WIDTH * HEIGHT * 4]));
let mut layer = BackgroundLayer {
rom,
graphics: None,
palette_cycle: None,
pixels: pixels.clone(),
distorter: Distorter::new(pixels),
entry: 0,
};
layer.load_entry(entry);
layer
}
pub fn overlay_frame(
&mut self,
bitmap: &mut [u8],
letterbox: u8,
ticks: u64,
alpha: f32,
erase: bool,
) {
if let Some(palette_cycle) = &mut self.palette_cycle {
palette_cycle.cycle();
self.graphics
.as_ref()
.unwrap()
.borrow_mut()
.draw(&mut self.pixels.borrow_mut(), palette_cycle);
}
self.distorter
.overlay_frame(bitmap, letterbox, ticks, alpha, erase);
}
fn load_graphics(&mut self, index: usize) {
self.graphics = Some(self.rom.borrow_mut().get_background_graphics(index));
}
fn load_palette(&mut self, background: &BattleBackground) {
self.palette_cycle = Some(PaletteCycle::new(
background,
self.rom
.borrow_mut()
.get_background_palette(background.palette_index()),
))
}
fn load_effect(&mut self, index: usize) {
*self.distorter.effect.borrow_mut() = DistortionEffect::new(index);
}
fn load_entry(&mut self, index: usize) {
self.entry = index;
let background = self.rom.borrow_mut().get_battle_background(index);
self.load_graphics(background.borrow().graphics_index());
self.load_palette(&background.borrow());
let animation = background.borrow().animation();
let e1 = (animation >> 24) & 0xFF;
let e2 = (animation >> 16) & 0xFF;
if e2 != 0 {
self.load_effect(e2 as usize);
} else {
self.load_effect(e1 as usize);
}
}
}