use agb::display::GraphicsFrame;
use agb::display::tiled::BackgroundId;
use agb::fixnum::{Num, num};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum Fade {
Start,
Step1,
Step2,
Step3,
Step4,
Step5,
End,
}
impl Fade {
pub fn next(self) -> Option<Self> {
match self {
Fade::Start => Some(Fade::Step1),
Fade::Step1 => Some(Fade::Step2),
Fade::Step2 => Some(Fade::Step3),
Fade::Step3 => Some(Fade::Step4),
Fade::Step4 => Some(Fade::Step5),
Fade::Step5 => Some(Fade::End),
Fade::End => None,
}
}
}
impl From<Fade> for FadeAmount {
fn from(value: Fade) -> Self {
match value {
Fade::Start => num!(0),
Fade::Step1 => num!(0.1875),
Fade::Step2 => num!(0.3125),
Fade::Step3 => num!(0.5),
Fade::Step4 => num!(0.6875),
Fade::Step5 => num!(0.8125),
Fade::End => num!(1),
}
}
}
pub type FadeAmount = Num<u8, 4>;
enum FadeKind {
Darken,
Brighten,
}
fn apply_fade(
kind: FadeKind,
amount: FadeAmount,
bg_ids: &[BackgroundId],
frame: &mut GraphicsFrame,
) {
let mut effect = match kind {
FadeKind::Darken => frame.blend().darken(amount),
FadeKind::Brighten => frame.blend().brighten(amount),
};
effect.enable_object();
for id in bg_ids {
effect.enable_background(*id);
}
}
pub fn fade_to_black<A: Into<FadeAmount>>(
amount: A,
bg_ids: &[BackgroundId],
frame: &mut GraphicsFrame,
) {
apply_fade(FadeKind::Darken, amount.into(), bg_ids, frame);
}
pub fn fade_from_black<A: Into<FadeAmount>>(
amount: A,
bg_ids: &[BackgroundId],
frame: &mut GraphicsFrame,
) {
apply_fade(FadeKind::Darken, num!(1) - amount.into(), bg_ids, frame);
}
pub fn fade_to_white<A: Into<FadeAmount>>(
amount: A,
bg_ids: &[BackgroundId],
frame: &mut GraphicsFrame,
) {
apply_fade(FadeKind::Brighten, amount.into(), bg_ids, frame);
}
pub fn fade_from_white<A: Into<FadeAmount>>(
amount: A,
bg_ids: &[BackgroundId],
frame: &mut GraphicsFrame,
) {
apply_fade(FadeKind::Brighten, num!(1) - amount.into(), bg_ids, frame);
}
pub fn reset_fade(bg_ids: &[BackgroundId], frame: &mut GraphicsFrame) {
apply_fade(FadeKind::Brighten, num!(0), bg_ids, frame);
}