diff --git a/lib/snf/src/newtypes/common.rs b/lib/snf/src/newtypes/common.rs index cec7e09..6fdec07 100644 --- a/lib/snf/src/newtypes/common.rs +++ b/lib/snf/src/newtypes/common.rs @@ -1,3 +1,9 @@ pub const fn flag(b:bool,mask:u8)->u8{ (-(b as i8) as u8)&mask } +pub fn bool_from_u8(value:u8)->bool{ + value!=0 +} +pub fn bool_into_u8(value:&bool)->u8{ + *value as u8 +} diff --git a/lib/snf/src/newtypes/integer.rs b/lib/snf/src/newtypes/integer.rs index 0eb7711..6d125e2 100644 --- a/lib/snf/src/newtypes/integer.rs +++ b/lib/snf/src/newtypes/integer.rs @@ -38,6 +38,23 @@ pub struct Ratio64Vec2{ pub x:Ratio64, pub y:Ratio64, } +impl TryInto for Ratio64Vec2{ + type Error=RatioError; + fn try_into(self)->Result{ + Ok(strafesnet_common::integer::Ratio64Vec2{ + x:self.x.try_into()?, + y:self.y.try_into()?, + }) + } +} +impl From for Ratio64Vec2{ + fn from(value:strafesnet_common::integer::Ratio64Vec2)->Self{ + Self{ + x:value.x.into(), + y:value.y.into(), + } + } +} pub type Angle32=i32; pub type Planar64=i64; diff --git a/lib/snf/src/newtypes/mod.rs b/lib/snf/src/newtypes/mod.rs index 19e2e59..ec97ed7 100644 --- a/lib/snf/src/newtypes/mod.rs +++ b/lib/snf/src/newtypes/mod.rs @@ -1,7 +1,9 @@ mod common; pub mod aabb; pub mod model; +pub mod mouse; pub mod integer; +pub mod physics; pub mod gameplay_modes; pub mod gameplay_style; pub mod gameplay_attributes; diff --git a/lib/snf/src/newtypes/mouse.rs b/lib/snf/src/newtypes/mouse.rs new file mode 100644 index 0000000..1fd6f3b --- /dev/null +++ b/lib/snf/src/newtypes/mouse.rs @@ -0,0 +1,25 @@ +use super::integer::Time; + +#[binrw::binrw] +#[brw(little)] +pub struct MouseState{ + pub pos:[i32;2], + pub time:Time, +} + +impl Into> for MouseState{ + fn into(self)->strafesnet_common::mouse::MouseState{ + strafesnet_common::mouse::MouseState{ + pos:self.pos.into(), + time:strafesnet_common::integer::Time::raw(self.time), + } + } +} +impl From> for MouseState{ + fn from(value:strafesnet_common::mouse::MouseState)->Self{ + Self{ + pos:value.pos.to_array(), + time:value.time.get(), + } + } +} diff --git a/lib/snf/src/newtypes/physics.rs b/lib/snf/src/newtypes/physics.rs new file mode 100644 index 0000000..d83994e --- /dev/null +++ b/lib/snf/src/newtypes/physics.rs @@ -0,0 +1,153 @@ +use super::integer::Time; +use super::common::{bool_from_u8,bool_into_u8}; + +type TimedPhysicsInstruction=strafesnet_common::instruction::TimedInstruction; + +#[binrw::binrw] +#[brw(little)] +pub struct TimedInstruction{ + pub time:Time, + pub instruction:Instruction, +} + +impl TryInto for TimedInstruction{ + type Error=super::integer::RatioError; + fn try_into(self)->Result{ + Ok(strafesnet_common::instruction::TimedInstruction{ + time:strafesnet_common::integer::Time::raw(self.time), + instruction:self.instruction.try_into()?, + }) + } +} +impl TryFrom for TimedInstruction{ + type Error=super::physics::InstructionConvert; + fn try_from(value:TimedPhysicsInstruction)->Result{ + Ok(Self{ + time:value.time.get(), + instruction:value.instruction.try_into()?, + }) + } +} +#[binrw::binrw] +#[brw(little)] +pub enum Instruction{ + #[brw(magic=0u8)] + ReplaceMouse{ + m0:super::mouse::MouseState, + m1:super::mouse::MouseState + }, + #[brw(magic=1u8)] + SetNextMouse(super::mouse::MouseState), + #[brw(magic=2u8)] + SetMoveRight( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=3u8)] + SetMoveUp( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=4u8)] + SetMoveBack( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=5u8)] + SetMoveLeft( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=6u8)] + SetMoveDown( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=7u8)] + SetMoveForward( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=8u8)] + SetJump( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=9u8)] + SetZoom( + #[br(map=bool_from_u8)] + #[bw(map=bool_into_u8)] + bool), + #[brw(magic=10u8)] + Reset, + #[brw(magic=11u8)] + Restart(super::gameplay_modes::ModeId), + #[brw(magic=12u8)] + Spawn(super::gameplay_modes::ModeId,super::gameplay_modes::StageId), + #[brw(magic=13u8)] + PracticeFly, + #[brw(magic=14u8)] + SetSensitivity(super::integer::Ratio64Vec2), +} +#[derive(Debug)] +pub enum InstructionConvert{ + /// This is an instruction that can be dropped when serializing + DropInstruction, +} +impl std::fmt::Display for InstructionConvert{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for InstructionConvert{} +impl TryInto for Instruction{ + type Error=super::integer::RatioError; + fn try_into(self)->Result{ + Ok(match self{ + Instruction::ReplaceMouse{m0,m1}=>strafesnet_common::physics::Instruction::Mouse(strafesnet_common::physics::MouseInstruction::ReplaceMouse{m0:m0.into(),m1:m1.into()}), + Instruction::SetNextMouse(m)=>strafesnet_common::physics::Instruction::Mouse(strafesnet_common::physics::MouseInstruction::SetNextMouse(m.into())), + Instruction::SetMoveRight(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveRight(state.into())), + Instruction::SetMoveUp(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveUp(state.into())), + Instruction::SetMoveBack(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveBack(state.into())), + Instruction::SetMoveLeft(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveLeft(state.into())), + Instruction::SetMoveDown(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveDown(state.into())), + Instruction::SetMoveForward(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveForward(state.into())), + Instruction::SetJump(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetJump(state.into())), + Instruction::SetZoom(state)=>strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetZoom(state.into())), + Instruction::Reset=>strafesnet_common::physics::Instruction::Mode(strafesnet_common::physics::ModeInstruction::Reset), + Instruction::Restart(mode_id)=>strafesnet_common::physics::Instruction::Mode(strafesnet_common::physics::ModeInstruction::Restart(strafesnet_common::gameplay_modes::ModeId::new(mode_id))), + Instruction::Spawn(mode_id,stage_id)=>strafesnet_common::physics::Instruction::Mode(strafesnet_common::physics::ModeInstruction::Spawn( + strafesnet_common::gameplay_modes::ModeId::new(mode_id), + strafesnet_common::gameplay_modes::StageId::new(stage_id), + )), + Instruction::PracticeFly=>strafesnet_common::physics::Instruction::Misc(strafesnet_common::physics::MiscInstruction::PracticeFly), + Instruction::SetSensitivity(sensitivity)=>strafesnet_common::physics::Instruction::Misc(strafesnet_common::physics::MiscInstruction::SetSensitivity(sensitivity.try_into()?)), + }) + } +} +impl TryFrom for Instruction{ + type Error=InstructionConvert; + fn try_from(value:strafesnet_common::physics::Instruction)->Result{ + match value{ + strafesnet_common::physics::Instruction::Mouse(strafesnet_common::physics::MouseInstruction::ReplaceMouse{m0,m1})=>Ok(Instruction::ReplaceMouse{m0:m0.into(),m1:m1.into()}), + strafesnet_common::physics::Instruction::Mouse(strafesnet_common::physics::MouseInstruction::SetNextMouse(m))=>Ok(Instruction::SetNextMouse(m.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveRight(state))=>Ok(Instruction::SetMoveRight(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveUp(state))=>Ok(Instruction::SetMoveUp(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveBack(state))=>Ok(Instruction::SetMoveBack(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveLeft(state))=>Ok(Instruction::SetMoveLeft(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveDown(state))=>Ok(Instruction::SetMoveDown(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetMoveForward(state))=>Ok(Instruction::SetMoveForward(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetJump(state))=>Ok(Instruction::SetJump(state.into())), + strafesnet_common::physics::Instruction::SetControl(strafesnet_common::physics::SetControlInstruction::SetZoom(state))=>Ok(Instruction::SetZoom(state.into())), + strafesnet_common::physics::Instruction::Mode(strafesnet_common::physics::ModeInstruction::Reset)=>Ok(Instruction::Reset), + strafesnet_common::physics::Instruction::Mode(strafesnet_common::physics::ModeInstruction::Restart(mode_id))=>Ok(Instruction::Restart(mode_id.get())), + strafesnet_common::physics::Instruction::Mode(strafesnet_common::physics::ModeInstruction::Spawn(mode_id,stage_id))=>Ok(Instruction::Spawn( + mode_id.get(), + stage_id.get(), + )), + strafesnet_common::physics::Instruction::Misc(strafesnet_common::physics::MiscInstruction::PracticeFly)=>Ok(Instruction::PracticeFly), + strafesnet_common::physics::Instruction::Misc(strafesnet_common::physics::MiscInstruction::SetSensitivity(sensitivity))=>Ok(Instruction::SetSensitivity(sensitivity.into())), + strafesnet_common::physics::Instruction::Idle=>Err(InstructionConvert::DropInstruction), + } + } +}