pub a: u8,
}
+impl Default for Color {
+ fn default() -> Self {
+ Self::WHITE
+ }
+}
+
impl Color {
pub const WHITE: Self = Self {
r: 255,
pub fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
Self { r, g, b, a }
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Color, usize), ()> {
+ if data.len() < offset + 4 {
+ Err(())
+ } else {
+ let mut color = Color::WHITE;
+
+ color.r = data[offset];
+ color.g = data[offset + 1];
+ color.b = data[offset + 2];
+ color.a = data[offset + 3];
+
+ Ok((color, 4))
+ }
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ bytes.push(self.r);
+ bytes.push(self.g);
+ bytes.push(self.b);
+ bytes.push(self.a);
+
+ bytes
+ }
}
#[derive(Copy, Clone, Debug, PartialEq)]
self.x += v.x;
self.y += v.y;
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Rectangle, usize), ()> {
+ if data.len() < offset + std::mem::size_of::<f32>() * 4 {
+ return Err(());
+ }
+
+ let mut idx: usize = 0;
+ let mut rect = Rectangle::new(0.0, 0.0, 0.0, 0.0);
+
+ rect.x = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+ rect.y = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+ rect.w = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+ rect.h = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ Ok((rect, idx))
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ for byte in self.x.to_be_bytes() {
+ bytes.push(byte);
+ }
+ for byte in self.y.to_be_bytes() {
+ bytes.push(byte);
+ }
+ for byte in self.w.to_be_bytes() {
+ bytes.push(byte);
+ }
+ for byte in self.h.to_be_bytes() {
+ bytes.push(byte);
+ }
+
+ bytes
+ }
}
impl Default for Rectangle {
pub r: f32,
}
+impl Default for Circle {
+ fn default() -> Self {
+ Self {
+ x: 0.0,
+ y: 0.0,
+ r: 1.0,
+ }
+ }
+}
+
impl Circle {
pub fn new(x: f32, y: f32, r: f32) -> Self {
Self { x, y, r }
self.x += v.x;
self.y += v.y;
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Circle, usize), ()> {
+ if data.len() < 12 + offset {
+ return Err(());
+ }
+
+ let mut idx: usize = 0;
+ let mut circle = Circle::new(0.0, 0.0, 1.0);
+
+ circle.x = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ circle.y = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ circle.r = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ Ok((circle, idx))
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ for byte in self.x.to_be_bytes() {
+ bytes.push(byte);
+ }
+ for byte in self.y.to_be_bytes() {
+ bytes.push(byte);
+ }
+ for byte in self.r.to_be_bytes() {
+ bytes.push(byte);
+ }
+
+ bytes
+ }
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub y: f32,
}
+impl Default for Vector {
+ fn default() -> Self {
+ Self { x: 1.0, y: 1.0 }
+ }
+}
+
impl Add<Vector> for Vector {
type Output = Vector;
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Vector, usize), ()> {
+ let mut idx: usize = 0;
+ let mut vector = Vector::new(0.0, 0.0);
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ vector.x = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ vector.y = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ Ok((vector, idx))
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ for byte in self.x.to_be_bytes() {
+ bytes.push(byte);
+ }
+ for byte in self.y.to_be_bytes() {
+ bytes.push(byte);
+ }
+
+ bytes
+ }
}
impl From<(f32, f32)> for Vector {
life_timer: f32,
}
+impl Default for Particle {
+ fn default() -> Self {
+ Self {
+ rect: Rectangle::new(0.0, 0.0, 1.0, 1.0),
+ circle: Circle::new(0.0, 0.0, 1.0),
+ is_rect: true,
+ velx: 0.0,
+ vely: 0.0,
+ velr: 0.0,
+ r: 1.0,
+ lifetime: 1.0,
+ life_timer: 0.0,
+ }
+ }
+}
+
+impl Particle {
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Particle, usize), ()> {
+ let mut idx: usize = 0;
+ let mut particle = Particle::default();
+
+ let (rect, rect_size) = Rectangle::deserialize(data, offset + idx)?;
+ particle.rect = rect;
+ idx += rect_size;
+
+ let (circle, circle_size) = Circle::deserialize(data, offset + idx)?;
+ particle.circle = circle;
+ idx += circle_size;
+
+ if data.len() < offset + idx + 1 {
+ return Err(());
+ }
+ particle.is_rect = data[offset + idx] != 0;
+ idx += 1;
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ particle.velx = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ particle.vely = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ particle.velr = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ particle.r = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ particle.lifetime = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ particle.life_timer = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ Ok((particle, idx))
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ bytes.append(&mut self.rect.serialize());
+ bytes.append(&mut self.circle.serialize());
+ bytes.push(if self.is_rect { 1 } else { 0 });
+ bytes.append(&mut self.velx.to_be_bytes().into());
+ bytes.append(&mut self.vely.to_be_bytes().into());
+ bytes.append(&mut self.velr.to_be_bytes().into());
+ bytes.append(&mut self.r.to_be_bytes().into());
+ bytes.append(&mut self.lifetime.to_be_bytes().into());
+ bytes.append(&mut self.life_timer.to_be_bytes().into());
+
+ bytes
+ }
+}
+
#[derive(Clone)]
struct ParticleSystem {
particles: Vec<Particle>,
vel_multiplier: f32,
}
+impl Default for ParticleSystem {
+ fn default() -> Self {
+ Self {
+ particles: Vec::new(),
+ spawn_timer: 0.0,
+ spawn_time: 1.0,
+ lifetime: 1.0,
+ host_rect: Rectangle::default(),
+ host_circle: Circle::default(),
+ is_rect: true,
+ direction: Vector::default(),
+ color: Color::default(),
+ opacity: 1.0,
+ vel_multiplier: 1.0,
+ }
+ }
+}
+
impl ParticleSystem {
fn new(
spawn_time: f32,
});
}
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Self, usize), ()> {
+ let mut idx: usize = 0;
+ let mut psystem = ParticleSystem::default();
+
+ if data.len() < offset + idx + std::mem::size_of::<usize>() {
+ return Err(());
+ }
+ let particles_len: usize = usize::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<usize>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<usize>();
+
+ let mut particles: Vec<Particle> = Vec::new();
+ for _ in 0..particles_len {
+ let (particle, particle_size) = Particle::deserialize(data, offset + idx)?;
+ particles.push(particle);
+ idx += particle_size;
+ }
+ psystem.particles = particles;
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ psystem.spawn_timer = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ psystem.spawn_time = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ psystem.lifetime = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ let (rect, rect_size) = Rectangle::deserialize(data, offset + idx)?;
+ psystem.host_rect = rect;
+ idx += rect_size;
+
+ let (circle, circle_size) = Circle::deserialize(data, offset + idx)?;
+ psystem.host_circle = circle;
+ idx += circle_size;
+
+ if data.len() < offset + idx + 1 {
+ return Err(());
+ }
+ psystem.is_rect = data[offset + idx] != 0;
+ idx += 1;
+
+ let (vector, vector_size) = Vector::deserialize(data, offset + idx)?;
+ psystem.direction = vector;
+ idx += vector_size;
+
+ let (color, color_size) = Color::deserialize(data, offset + idx)?;
+ psystem.color = color;
+ idx += color_size;
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ psystem.opacity = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ psystem.vel_multiplier = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ Ok((psystem, idx))
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ let particle_count: usize = self.particles.len();
+ bytes.append(&mut particle_count.to_be_bytes().into());
+ todo!();
+
+ bytes
+ }
}
#[derive(Clone)]
offset: f32,
}
+impl Default for RotatingParticleSystem {
+ fn default() -> Self {
+ Self {
+ particle_system: ParticleSystem::default(),
+ r: 0.0,
+ velr: 0.2,
+ offset: 0.0,
+ }
+ }
+}
+
impl RotatingParticleSystem {
fn new(
spawn_time: f32,
.ok();
}
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<(Self, usize), ()> {
+ let mut idx: usize = 0;
+ let mut rpsystem = RotatingParticleSystem::default();
+
+ let (psystem, psystem_size) = ParticleSystem::deserialize(data, offset + idx)?;
+ rpsystem.particle_system = psystem;
+ idx += psystem_size;
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ rpsystem.r = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ rpsystem.velr = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ if data.len() < offset + idx + std::mem::size_of::<f32>() {
+ return Err(());
+ }
+ rpsystem.offset = f32::from_be_bytes(
+ data[(offset + idx)..(offset + idx + std::mem::size_of::<f32>())]
+ .try_into()
+ .map_err(|_| ())?,
+ );
+ idx += std::mem::size_of::<f32>();
+
+ Ok((rpsystem, idx))
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ let mut bytes = Vec::new();
+
+ todo!();
+
+ bytes
+ }
}
struct ExplConvCircleParticle {
moon.draw(window, transform);
}
}
+
+ pub fn deserialize(data: &[u8], offset: usize) -> Result<Planet, ()> {
+ let mut idx: usize = 0;
+ let mut planet = Planet::new(Circle::new(0.0, 0.0, 1.0), Color::WHITE);
+
+ let (circle, circle_size) = Circle::deserialize(data, offset + idx)?;
+ planet.circle = circle;
+ idx += circle_size;
+
+ let (color, color_size) = Color::deserialize(data, offset + idx)?;
+ planet.color = color;
+ idx += color_size;
+
+ let (psystem, psystem_size) = ParticleSystem::deserialize(data, offset + idx)?;
+ planet.particle_system = psystem;
+ idx += psystem_size;
+
+ todo!("deserialize rotatingparticlesystem");
+ Err(())
+ }
}
#[derive(Clone)]
joining_particles: RotatingParticleSystem,
}
+const SAVE_DATA_IDENTIFIER: [u8; 4] = [0x53, 0x41, 0x56, 0x45];
+#[derive(Copy, Clone)]
+enum SaveDataDeserializeState {
+ GET_IDENTIFIER,
+ GET_PLANETS,
+}
+
+impl SaveData {
+ pub fn deserialize(data: &[u8]) -> Result<SaveData, ()> {
+ let mut idx: usize = 0;
+ let mut save_data = SaveData {
+ planets: Vec::new(),
+ stars: Vec::new(),
+ fishes: Vec::new(),
+ player: Rectangle::new(0.0, 0.0, 0.0, 0.0),
+ joining_particles: RotatingParticleSystem::new(
+ PP_GEN_RATE,
+ 1.0,
+ Rectangle::new(400.0, 300.0, 16.0, 16.0),
+ Circle::new(100.0, 100.0, 32.0),
+ true,
+ Vector::new(0.0, 0.0),
+ Color::GREEN,
+ 0.0,
+ 0.0,
+ 0.1,
+ JOINING_FAR_DIST,
+ 1.0,
+ ),
+ };
+ let mut state = SaveDataDeserializeState::GET_IDENTIFIER;
+
+ while idx < data.len() {
+ match state {
+ SaveDataDeserializeState::GET_IDENTIFIER => {
+ for i in 0..SAVE_DATA_IDENTIFIER.len() {
+ if data[idx + i] != SAVE_DATA_IDENTIFIER[i] {
+ return Err(());
+ }
+ }
+ idx += SAVE_DATA_IDENTIFIER.len();
+ state = SaveDataDeserializeState::GET_PLANETS;
+ }
+ SaveDataDeserializeState::GET_PLANETS => todo!(),
+ }
+ }
+
+ Err(())
+ }
+
+ pub fn serialize(&self) -> Vec<u8> {
+ todo!();
+ }
+}
+
enum SaveLoadNotification {
Save { text: Option<String>, timer: f32 },
Load { text: Option<String>, timer: f32 },