use crate::common::{Reset, ResetKind};
use bitflags::bitflags;
use serde::{Deserialize, Serialize};
#[derive(Default, Serialize, Deserialize, Debug, Copy, Clone)]
#[must_use]
pub struct Status {
pub in_vblank: bool,
pub spr_zero_hit: bool,
pub spr_overflow: bool,
pub bits: Bits,
}
bitflags! {
#[derive(Default, Serialize, Deserialize, Debug, Copy, Clone)]
#[must_use]
pub struct Bits: u8 {
const UNUSED1 = 0x01;
const UNUSED2 = 0x02;
const UNUSED3 = 0x04;
const UNUSED4 = 0x08;
const UNUSED5 = 0x10;
const SPR_OVERFLOW = 0x20;
const SPR_ZERO_HIT = 0x40;
const VBLANK_STARTED = 0x80;
}
}
impl Status {
pub fn new() -> Self {
let mut status = Self::default();
status.write(0);
status
}
#[inline]
pub const fn write(&mut self, val: u8) {
self.bits = Bits::from_bits_truncate(val);
self.spr_overflow = self.bits.contains(Bits::SPR_ZERO_HIT);
self.spr_zero_hit = self.bits.contains(Bits::SPR_ZERO_HIT);
self.in_vblank = self.bits.contains(Bits::VBLANK_STARTED);
}
#[inline(always)]
#[must_use]
pub const fn read(&self) -> u8 {
self.bits.bits()
}
#[inline(always)]
pub fn set_spr_overflow(&mut self, val: bool) {
self.bits.set(Bits::SPR_OVERFLOW, val);
self.spr_overflow = val;
}
#[inline(always)]
pub fn set_spr_zero_hit(&mut self, val: bool) {
self.bits.set(Bits::SPR_ZERO_HIT, val);
self.spr_zero_hit = val;
}
#[inline(always)]
pub fn set_in_vblank(&mut self, val: bool) {
self.bits.set(Bits::VBLANK_STARTED, val);
self.in_vblank = val;
}
#[inline(always)]
pub fn reset_in_vblank(&mut self) {
self.bits.remove(Bits::VBLANK_STARTED);
self.in_vblank = false;
}
}
impl Reset for Status {
fn reset(&mut self, kind: ResetKind) {
if kind == ResetKind::Hard {
self.set_in_vblank(false); self.set_spr_zero_hit(false);
self.set_spr_overflow(false); }
}
}