#![allow(unused_variables)]
use std::{
io::{Result, Write},
mem::size_of,
};
use byteorder::WriteBytesExt;
use crate::{
frame::{
PortOccupancy,
immutable::{Data, Frame, PortData},
},
io::slippi::{Version, de::Event},
};
type BE = byteorder::BigEndian;
impl Data {
fn write_pre<W: Write>(
&self,
w: &mut W,
version: Version,
idx: usize,
frame_id: i32,
port: PortOccupancy,
) -> Result<()> {
if self.validity.as_ref().map_or(true, |v| v.get_bit(idx)) {
w.write_u8(Event::FramePre as u8)?;
w.write_i32::<BE>(frame_id)?;
w.write_u8(port.port as u8)?;
w.write_u8(match port.follower {
true => 1,
_ => 0,
})?;
self.pre.write(w, version, idx)?;
}
Ok(())
}
fn write_post<W: Write>(
&self,
w: &mut W,
version: Version,
idx: usize,
frame_id: i32,
port: PortOccupancy,
) -> Result<()> {
if self.validity.as_ref().map_or(true, |v| v.get_bit(idx)) {
w.write_u8(Event::FramePost as u8)?;
w.write_i32::<BE>(frame_id)?;
w.write_u8(port.port as u8)?;
w.write_u8(match port.follower {
true => 1,
_ => 0,
})?;
self.post.write(w, version, idx)?;
}
Ok(())
}
}
impl PortData {
fn write_pre<W: Write>(
&self,
w: &mut W,
version: Version,
idx: usize,
frame_id: i32,
) -> Result<()> {
self.leader.write_pre(
w,
version,
idx,
frame_id,
PortOccupancy {
port: self.port,
follower: false,
},
)?;
self.follower.as_ref().map_or(Ok(()), |f| {
if f.validity.as_ref().map_or(true, |v| v.get_bit(idx)) {
f.write_pre(
w,
version,
idx,
frame_id,
PortOccupancy {
port: self.port,
follower: true,
},
)
} else {
Ok(())
}
})
}
fn write_post<W: Write>(
&self,
w: &mut W,
version: Version,
idx: usize,
frame_id: i32,
) -> Result<()> {
self.leader.write_post(
w,
version,
idx,
frame_id,
PortOccupancy {
port: self.port,
follower: false,
},
)?;
self.follower.as_ref().map_or(Ok(()), |f| {
if f.validity.as_ref().map_or(true, |v| v.get_bit(idx)) {
f.write_post(
w,
version,
idx,
frame_id,
PortOccupancy {
port: self.port,
follower: true,
},
)
} else {
Ok(())
}
})
}
}
impl Frame {
pub fn write<W: Write>(&self, w: &mut W, version: Version) -> Result<()> {
for (idx, &frame_id) in self.id.values().iter().enumerate() {
if version.gte(2, 2) {
w.write_u8(Event::FrameStart as u8)?;
w.write_i32::<BE>(frame_id)?;
self.start.as_ref().unwrap().write(w, version, idx)?;
}
for port in &self.ports {
port.write_pre(w, version, idx, frame_id)?;
}
if version.gte(3, 18) {
let offset = self.fod_platform_offset.as_ref().unwrap();
for evt_idx in (offset[idx] as usize)..(offset[idx + 1] as usize) {
w.write_u8(Event::FodPlatform as u8)?;
w.write_i32::<BE>(frame_id)?;
self.fod_platform
.as_ref()
.unwrap()
.write(w, version, evt_idx)?;
}
let offset = self.dreamland_whispy_offset.as_ref().unwrap();
for evt_idx in (offset[idx] as usize)..(offset[idx + 1] as usize) {
w.write_u8(Event::DreamlandWhispy as u8)?;
w.write_i32::<BE>(frame_id)?;
self.dreamland_whispy
.as_ref()
.unwrap()
.write(w, version, evt_idx)?;
}
let offset = self.stadium_transformation_offset.as_ref().unwrap();
for evt_idx in (offset[idx] as usize)..(offset[idx + 1] as usize) {
w.write_u8(Event::StadiumTransformation as u8)?;
w.write_i32::<BE>(frame_id)?;
self.stadium_transformation
.as_ref()
.unwrap()
.write(w, version, evt_idx)?;
}
}
if version.gte(3, 0) {
let offset = self.item_offset.as_ref().unwrap();
for item_idx in (offset[idx] as usize)..(offset[idx + 1] as usize) {
w.write_u8(Event::Item as u8)?;
w.write_i32::<BE>(frame_id)?;
self.item.as_ref().unwrap().write(w, version, item_idx)?;
}
}
for port in &self.ports {
port.write_post(w, version, idx, frame_id)?;
}
if version.gte(3, 0) {
w.write_u8(Event::FrameEnd as u8)?;
w.write_i32::<BE>(frame_id)?;
self.end.as_ref().unwrap().write(w, version, idx)?;
}
}
Ok(())
}
}
use crate::frame::immutable::DreamlandWhispy;
impl DreamlandWhispy {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u8(self.direction.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u8>();
size
}
}
use crate::frame::immutable::End;
impl End {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
if version.gte(3, 7) {
w.write_i32::<BE>(self.latest_finalized_frame.as_ref().unwrap().value(i))?
};
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
if version.gte(3, 7) {
size += size_of::<i32>()
};
size
}
}
use crate::frame::immutable::FodPlatform;
impl FodPlatform {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u8(self.platform.value(i))?;
w.write_f32::<BE>(self.height.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u8>();
size += size_of::<f32>();
size
}
}
use crate::frame::immutable::Item;
impl Item {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u16::<BE>(self.r#type.value(i))?;
w.write_u8(self.state.value(i))?;
w.write_f32::<BE>(self.direction.value(i))?;
self.velocity.write(w, version, i)?;
self.position.write(w, version, i)?;
w.write_u16::<BE>(self.damage.value(i))?;
w.write_f32::<BE>(self.timer.value(i))?;
w.write_u32::<BE>(self.id.value(i))?;
if version.gte(3, 2) {
self.misc.as_ref().unwrap().write(w, version, i)?;
if version.gte(3, 6) {
w.write_i8(self.owner.as_ref().unwrap().value(i))?;
if version.gte(3, 16) {
w.write_u16::<BE>(self.instance_id.as_ref().unwrap().value(i))?
}
}
};
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u16>();
size += size_of::<u8>();
size += size_of::<f32>();
size += Velocity::size(version);
size += Position::size(version);
size += size_of::<u16>();
size += size_of::<f32>();
size += size_of::<u32>();
if version.gte(3, 2) {
size += ItemMisc::size(version);
if version.gte(3, 6) {
size += size_of::<i8>();
if version.gte(3, 16) {
size += size_of::<u16>()
}
}
};
size
}
}
use crate::frame::immutable::ItemMisc;
impl ItemMisc {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u8(self.0.value(i))?;
w.write_u8(self.1.value(i))?;
w.write_u8(self.2.value(i))?;
w.write_u8(self.3.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
size
}
}
use crate::frame::immutable::Position;
impl Position {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_f32::<BE>(self.x.value(i))?;
w.write_f32::<BE>(self.y.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<f32>();
size += size_of::<f32>();
size
}
}
use crate::frame::immutable::Post;
impl Post {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u8(self.character.value(i))?;
w.write_u16::<BE>(self.state.value(i))?;
self.position.write(w, version, i)?;
w.write_f32::<BE>(self.direction.value(i))?;
w.write_f32::<BE>(self.percent.value(i))?;
w.write_f32::<BE>(self.shield.value(i))?;
w.write_u8(self.last_attack_landed.value(i))?;
w.write_u8(self.combo_count.value(i))?;
w.write_u8(self.last_hit_by.value(i))?;
w.write_u8(self.stocks.value(i))?;
if version.gte(0, 2) {
w.write_f32::<BE>(self.state_age.as_ref().unwrap().value(i))?;
if version.gte(2, 0) {
self.state_flags.as_ref().unwrap().write(w, version, i)?;
w.write_f32::<BE>(self.misc_as.as_ref().unwrap().value(i))?;
w.write_u8(self.airborne.as_ref().unwrap().value(i))?;
w.write_u16::<BE>(self.ground.as_ref().unwrap().value(i))?;
w.write_u8(self.jumps.as_ref().unwrap().value(i))?;
w.write_u8(self.l_cancel.as_ref().unwrap().value(i))?;
if version.gte(2, 1) {
w.write_u8(self.hurtbox_state.as_ref().unwrap().value(i))?;
if version.gte(3, 5) {
self.velocities.as_ref().unwrap().write(w, version, i)?;
if version.gte(3, 8) {
w.write_f32::<BE>(self.hitlag.as_ref().unwrap().value(i))?;
if version.gte(3, 11) {
w.write_u32::<BE>(self.animation_index.as_ref().unwrap().value(i))?;
if version.gte(3, 16) {
w.write_u16::<BE>(
self.last_hit_by_instance.as_ref().unwrap().value(i),
)?;
w.write_u16::<BE>(self.instance_id.as_ref().unwrap().value(i))?
}
}
}
}
}
}
};
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u8>();
size += size_of::<u16>();
size += Position::size(version);
size += size_of::<f32>();
size += size_of::<f32>();
size += size_of::<f32>();
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
if version.gte(0, 2) {
size += size_of::<f32>();
if version.gte(2, 0) {
size += StateFlags::size(version);
size += size_of::<f32>();
size += size_of::<u8>();
size += size_of::<u16>();
size += size_of::<u8>();
size += size_of::<u8>();
if version.gte(2, 1) {
size += size_of::<u8>();
if version.gte(3, 5) {
size += Velocities::size(version);
if version.gte(3, 8) {
size += size_of::<f32>();
if version.gte(3, 11) {
size += size_of::<u32>();
if version.gte(3, 16) {
size += size_of::<u16>();
size += size_of::<u16>()
}
}
}
}
}
}
};
size
}
}
use crate::frame::immutable::Pre;
impl Pre {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u32::<BE>(self.random_seed.value(i))?;
w.write_u16::<BE>(self.state.value(i))?;
self.position.write(w, version, i)?;
w.write_f32::<BE>(self.direction.value(i))?;
self.joystick.write(w, version, i)?;
self.cstick.write(w, version, i)?;
w.write_f32::<BE>(self.triggers.value(i))?;
w.write_u32::<BE>(self.buttons.value(i))?;
w.write_u16::<BE>(self.buttons_physical.value(i))?;
self.triggers_physical.write(w, version, i)?;
if version.gte(1, 2) {
w.write_i8(self.raw_analog_x.as_ref().unwrap().value(i))?;
if version.gte(1, 4) {
w.write_f32::<BE>(self.percent.as_ref().unwrap().value(i))?;
if version.gte(3, 15) {
w.write_i8(self.raw_analog_y.as_ref().unwrap().value(i))?;
if version.gte(3, 17) {
w.write_i8(self.raw_analog_cstick_x.as_ref().unwrap().value(i))?;
w.write_i8(self.raw_analog_cstick_y.as_ref().unwrap().value(i))?
}
}
}
};
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u32>();
size += size_of::<u16>();
size += Position::size(version);
size += size_of::<f32>();
size += Position::size(version);
size += Position::size(version);
size += size_of::<f32>();
size += size_of::<u32>();
size += size_of::<u16>();
size += TriggersPhysical::size(version);
if version.gte(1, 2) {
size += size_of::<i8>();
if version.gte(1, 4) {
size += size_of::<f32>();
if version.gte(3, 15) {
size += size_of::<i8>();
if version.gte(3, 17) {
size += size_of::<i8>();
size += size_of::<i8>()
}
}
}
};
size
}
}
use crate::frame::immutable::StadiumTransformation;
impl StadiumTransformation {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u16::<BE>(self.event.value(i))?;
w.write_u16::<BE>(self.r#type.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u16>();
size += size_of::<u16>();
size
}
}
use crate::frame::immutable::Start;
impl Start {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u32::<BE>(self.random_seed.value(i))?;
if version.gte(3, 10) {
w.write_u32::<BE>(self.scene_frame_counter.as_ref().unwrap().value(i))?
};
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u32>();
if version.gte(3, 10) {
size += size_of::<u32>()
};
size
}
}
use crate::frame::immutable::StateFlags;
impl StateFlags {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_u8(self.0.value(i))?;
w.write_u8(self.1.value(i))?;
w.write_u8(self.2.value(i))?;
w.write_u8(self.3.value(i))?;
w.write_u8(self.4.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
size += size_of::<u8>();
size
}
}
use crate::frame::immutable::TriggersPhysical;
impl TriggersPhysical {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_f32::<BE>(self.l.value(i))?;
w.write_f32::<BE>(self.r.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<f32>();
size += size_of::<f32>();
size
}
}
use crate::frame::immutable::Velocities;
impl Velocities {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_f32::<BE>(self.self_x_air.value(i))?;
w.write_f32::<BE>(self.self_y.value(i))?;
w.write_f32::<BE>(self.knockback_x.value(i))?;
w.write_f32::<BE>(self.knockback_y.value(i))?;
w.write_f32::<BE>(self.self_x_ground.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<f32>();
size += size_of::<f32>();
size += size_of::<f32>();
size += size_of::<f32>();
size += size_of::<f32>();
size
}
}
use crate::frame::immutable::Velocity;
impl Velocity {
fn write<W: Write>(&self, w: &mut W, version: Version, i: usize) -> Result<()> {
w.write_f32::<BE>(self.x.value(i))?;
w.write_f32::<BE>(self.y.value(i))?;
Ok(())
}
pub(crate) fn size(version: Version) -> usize {
let mut size = 0usize;
size += size_of::<f32>();
size += size_of::<f32>();
size
}
}