pub const ANIM_BASE_TILE_ID: u8 = 0x31;
pub const NUM_SUBANIMS: usize = 86;
pub const NUM_FRAMEBLOCKS: usize = 122;
pub const NUM_BASECOORDS: usize = 177;
pub const FIRST_SE_ID: u8 = 0xD8;
pub const ANIM_END: u8 = 0xFF;
pub const OAM_XFLIP: u8 = 0x20;
pub const OAM_YFLIP: u8 = 0x40;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum SubAnimTransform {
Normal = 0,
HvFlip = 1,
HFlip = 2,
CoordFlip = 3,
Reverse = 4,
Enemy = 5,
}
impl SubAnimTransform {
pub fn from_u8(v: u8) -> Self {
match v {
0 => Self::Normal,
1 => Self::HvFlip,
2 => Self::HFlip,
3 => Self::CoordFlip,
4 => Self::Reverse,
5 => Self::Enemy,
_ => Self::Normal,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum FrameBlockMode {
Mode00 = 0,
Mode01 = 1,
Mode02 = 2,
Mode03 = 3,
Mode04 = 4,
}
impl FrameBlockMode {
pub fn from_u8(v: u8) -> Self {
match v {
0 => Self::Mode00,
1 => Self::Mode01,
2 => Self::Mode02,
3 => Self::Mode03,
4 => Self::Mode04,
_ => Self::Mode00,
}
}
pub fn has_delay(&self) -> bool {
matches!(
self,
Self::Mode00 | Self::Mode01 | Self::Mode03 | Self::Mode04
)
}
pub fn cleans_oam(&self) -> bool {
matches!(self, Self::Mode00 | Self::Mode01)
}
pub fn advances_dest(&self) -> bool {
matches!(self, Self::Mode02 | Self::Mode03)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum AnimationType {
None = 0,
ShakeScreenVertically = 1,
ShakeScreenHorizontallyHeavy = 2,
ShakeScreenHorizontallySlow = 3,
BlinkEnemyMonSprite = 4,
ShakeScreenHorizontallyLight = 5,
ShakeScreenHorizontallySlow2 = 6,
}
impl AnimationType {
pub fn from_u8(v: u8) -> Self {
match v {
1 => Self::ShakeScreenVertically,
2 => Self::ShakeScreenHorizontallyHeavy,
3 => Self::ShakeScreenHorizontallySlow,
4 => Self::BlinkEnemyMonSprite,
5 => Self::ShakeScreenHorizontallyLight,
6 => Self::ShakeScreenHorizontallySlow2,
_ => Self::None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum SpecialEffect {
WavyScreen = 0xD8,
SubstituteMon = 0xD9,
ShakeBackAndForth = 0xDA,
SlideEnemyMonOff = 0xDB,
ShowEnemyMonPic = 0xDC,
ShowMonPic = 0xDD,
BlinkEnemyMon = 0xDE,
HideEnemyMonPic = 0xDF,
FlashEnemyMonPic = 0xE0,
DelayAnimation10 = 0xE1,
SpiralBallsInward = 0xE2,
ShakeEnemyHud2 = 0xE3,
ShakeEnemyHud = 0xE4,
SlideMonHalfOff = 0xE5,
PetalsFalling = 0xE6,
LeavesFalling = 0xE7,
TransformMon = 0xE8,
SlideMonDownAndHide = 0xE9,
MinimizeMon = 0xEA,
BounceUpAndDown = 0xEB,
ShootManyBallsUpward = 0xEC,
ShootBallsUpward = 0xED,
SquishMonPic = 0xEE,
HideMonPic = 0xEF,
LightScreenPalette = 0xF0,
ResetMonPosition = 0xF1,
MoveMonHorizontally = 0xF2,
BlinkMon = 0xF3,
SlideMonOff = 0xF4,
FlashMonPic = 0xF5,
SlideMonDown = 0xF6,
SlideMonUp = 0xF7,
FlashScreenLong = 0xF8,
DarkenMonPalette = 0xF9,
WaterDropletsEverywhere = 0xFA,
ShakeScreen = 0xFB,
ResetScreenPalette = 0xFC,
DarkScreenPalette = 0xFD,
DarkScreenFlash = 0xFE,
}
impl SpecialEffect {
pub fn from_u8(v: u8) -> Option<Self> {
match v {
0xD8 => Some(Self::WavyScreen),
0xD9 => Some(Self::SubstituteMon),
0xDA => Some(Self::ShakeBackAndForth),
0xDB => Some(Self::SlideEnemyMonOff),
0xDC => Some(Self::ShowEnemyMonPic),
0xDD => Some(Self::ShowMonPic),
0xDE => Some(Self::BlinkEnemyMon),
0xDF => Some(Self::HideEnemyMonPic),
0xE0 => Some(Self::FlashEnemyMonPic),
0xE1 => Some(Self::DelayAnimation10),
0xE2 => Some(Self::SpiralBallsInward),
0xE3 => Some(Self::ShakeEnemyHud2),
0xE4 => Some(Self::ShakeEnemyHud),
0xE5 => Some(Self::SlideMonHalfOff),
0xE6 => Some(Self::PetalsFalling),
0xE7 => Some(Self::LeavesFalling),
0xE8 => Some(Self::TransformMon),
0xE9 => Some(Self::SlideMonDownAndHide),
0xEA => Some(Self::MinimizeMon),
0xEB => Some(Self::BounceUpAndDown),
0xEC => Some(Self::ShootManyBallsUpward),
0xED => Some(Self::ShootBallsUpward),
0xEE => Some(Self::SquishMonPic),
0xEF => Some(Self::HideMonPic),
0xF0 => Some(Self::LightScreenPalette),
0xF1 => Some(Self::ResetMonPosition),
0xF2 => Some(Self::MoveMonHorizontally),
0xF3 => Some(Self::BlinkMon),
0xF4 => Some(Self::SlideMonOff),
0xF5 => Some(Self::FlashMonPic),
0xF6 => Some(Self::SlideMonDown),
0xF7 => Some(Self::SlideMonUp),
0xF8 => Some(Self::FlashScreenLong),
0xF9 => Some(Self::DarkenMonPalette),
0xFA => Some(Self::WaterDropletsEverywhere),
0xFB => Some(Self::ShakeScreen),
0xFC => Some(Self::ResetScreenPalette),
0xFD => Some(Self::DarkScreenPalette),
0xFE => Some(Self::DarkScreenFlash),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FrameBlockTile {
pub x_px: u8,
pub y_px: u8,
pub tile_id: u8,
pub flags: u8,
}
#[derive(Debug, Clone)]
pub struct FrameBlock {
pub tiles: Vec<FrameBlockTile>,
}
impl FrameBlock {
pub const fn empty() -> Self {
Self { tiles: Vec::new() }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SubAnimFrame {
pub frame_block_id: u8,
pub base_coord_id: u8,
pub mode: FrameBlockMode,
}
#[derive(Debug, Clone)]
pub struct SubAnimation {
pub transform: SubAnimTransform,
pub frames: Vec<SubAnimFrame>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AnimCommand {
SubAnim {
sound_id: u8,
subanim_id: u8,
tileset: u8,
delay: u8,
},
Effect { sound_id: u8, effect: SpecialEffect },
}
#[derive(Debug, Clone)]
pub struct MoveAnimation {
pub commands: Vec<AnimCommand>,
}
impl MoveAnimation {
pub const fn empty() -> Self {
Self {
commands: Vec::new(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameHook {
FlashScreen,
FlashScreenEveryFour,
FlashScreenEveryEight,
BlizzardFlash,
Explode,
RockSlide,
Growl,
TailWhipUnused,
BallToss,
BallShake,
BallPoof,
TradeHideMonster,
TradeShakeBall,
TradeJumpBall,
}
pub const AMNESIA: u8 = 0x85;
pub const REST: u8 = 0x9C;
pub const CONF_ANIM: u8 = 0xBF;
pub const SLP_ANIM: u8 = 0xBD;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AnimTickResult {
Playing {
sound: Option<u8>,
hook: Option<AnimEffect>,
},
WaitDelay {
frames: u8,
sound: Option<u8>,
hook: Option<AnimEffect>,
},
Effect {
sound: Option<u8>,
effect: SpecialEffect,
},
Done,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AnimEffect {
None,
FlashScreen { frames: u8 },
ShakeScreenH { pixels: i8, frames: u8 },
ShakeScreenV { pixels: i8, frames: u8 },
ShakeScreenHV { pixels: i8, frames: u8 },
HidePlayerMon,
ShowPlayerMon,
HideEnemyMon,
ShowEnemyMon,
SlideEnemyMonOff,
SlidePlayerMonHalfOff,
SlidePlayerMonOff,
SlidePlayerMonDown,
SlidePlayerMonDownAndHide,
SlidePlayerMonUp,
ResetPlayerMonPosition,
MovePlayerMonH,
BlinkEnemyMon { times: u8 },
BlinkPlayerMon { times: u8 },
FlashEnemyMonPic,
FlashPlayerMonPic,
DarkScreenPalette,
LightScreenPalette,
ResetScreenPalette,
DarkenMonPalette,
WavyScreen,
SubstituteMon,
TransformMon,
MinimizeMon,
BounceUpAndDown,
SquishMonPic,
SpiralBallsInward,
ShootBallsUpward { many: bool },
PetalsFalling,
LeavesFalling,
WaterDroplets,
ShakeBackAndForth,
ShakeEnemyHud { variant: u8 },
Delay10,
}