Moved from verilog2logicworld

D4VID 1 month ago
parent b807c40589
commit 12aac05255

1
.gitignore vendored

@ -0,0 +1 @@
target/

@ -0,0 +1,47 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "binary_serialize_derive"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

@ -0,0 +1,12 @@
[package]
name = "binary_serialize_derive"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1.0.101"
quote = "1.0.40"
syn = { version = "2.0.106", features = ["full"] }

@ -0,0 +1,36 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(BinarySerializable)]
pub fn derive_binary_serializable(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let fields = match input.data {
syn::Data::Struct(s) => s.fields,
_ => panic!("#[derive(BinarySerializable)] only works on structs"),
};
let field_writes = fields.iter().map(|f| {
let ident = f.ident.as_ref().unwrap();
quote! {
BinarySerializable::write_to(&self.#ident, writer)?;
}
});
let expanded = quote! {
impl BinarySerializable for #name {
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
#(#field_writes)*
return Ok(());
}
}
};
TokenStream::from(expanded)
}

@ -0,0 +1,80 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "binary_serialize_derive"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "logicworld-subassembly"
version = "0.1.0"
dependencies = [
"binary_serialize_derive",
"quaternion",
"vecmath",
]
[[package]]
name = "piston-float"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad78bf43dcf80e8f950c92b84f938a0fc7590b7f6866fbcbeca781609c115590"
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quaternion"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a23cd933813dea6a8e24391c80634deba6a70ca5a14b2b944b8cb6d871e071"
dependencies = [
"vecmath",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "vecmath"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "956ae1e0d85bca567dee1dcf87fb1ca2e792792f66f87dced8381f99cd91156a"
dependencies = [
"piston-float",
]

@ -0,0 +1,9 @@
[package]
name = "logicworld-subassembly"
version = "0.1.0"
edition = "2021"
[dependencies]
binary_serialize_derive = { path = "../binary_serialize_derive" }
quaternion = "2.0.0"
vecmath = "1.0.0"

@ -0,0 +1,128 @@
use std::{
fs::{self, File}, i32, io::{self, Write}, path::Path
};
use crate::lw::{BinarySerializable, ComponentIdMap, ModVersion, Version};
pub mod lw;
enum SaveType {
_World = 1,
Subassembly = 2,
}
pub fn create_subassembly(
name: String,
path: &Path,
components: &[lw::Component],
wires: &[lw::Wire],
) -> io::Result<()> {
let directory = Path::join(path, &name);
fs::create_dir_all(&directory)?;
let mut file = File::create(Path::join(&directory, "data.partialworld"))?;
write_subassembly_file(&mut file, &components, &wires)?;
let mut placing_info_file = File::create(Path::join(&directory, "LastMainPlacingInfo.jecs"))?;
write_placing_info_file(&mut placing_info_file)?;
let mut placements_file = File::create(Path::join(&directory, "placements.jecs"))?;
write_placements_file(&mut placements_file)?;
let mut meta_file = File::create(Path::join(&directory, "meta.jecs"))?;
write_meta_file(&mut meta_file, &name)?;
return Ok(());
}
fn write_subassembly_file(
file: &mut impl Write,
components: &[lw::Component],
wires: &[lw::Wire],
) -> io::Result<()> {
// Header:
file.write_all(b"Logic World save")?; // Magic bytes
file.write_all(&[7 as u8])?; // Version 7
Version::new(0, 92, 0, 455).write_to(file)?; // Game Version
file.write_all(&[SaveType::Subassembly as u8])?;
(components.len() as i32).write_to(file)?;
(wires.len() as i32).write_to(file)?;
// Body:
let mods = vec![ModVersion {
id: "MHG".to_owned(),
version: Version::new(0, 91, 4, -1),
}];
mods.write_to(file)?;
let component_id_map = vec![ComponentIdMap {
numeric_id: 15,
text_id: "MHG.CircuitBoard".to_owned(),
}];
component_id_map.write_to(file)?;
for component in components {
component.write_to(file)?;
}
for wire in wires {
wire.write_to(file)?;
}
0i32.write_to(file)?; // We don't have any turned on nets
// Footer:
file.write_all(b"redstone sux lol")?;
return Ok(());
}
fn write_placing_info_file(file: &mut impl Write) -> io::Result<()> {
file.write_all(
b"PlacingInfo:
RaiseOnChangedEvents: true
Flipped: false
RotationAboutUpVector: 180
Offset:
x: 0
y: 0
BoardIsFlat: true
BoardRotationState: 0
",
)
}
fn write_placements_file(file: &mut impl Write) -> io::Result<()> {
file.write_all(
b"Placements:
-
CornerMidpointPositionBeforeFlipping:
x: 0
y: 0
z: 0
RotationBeforeFlipping:
x: 0
y: 0
z: 0
w: 1
PlacementType: OnTerrain
Flipped: false
BoardRotationState: 0
Type: Standard
data_format_version: 1
",
)
}
fn write_meta_file(file: &mut impl Write, title: &str) -> io::Result<()> {
file.write_all(
format!(
"Title: {}
Column: null
Category: null
",
title
)
.as_bytes(),
)
}

@ -0,0 +1,149 @@
use std::io::{self, Write};
use binary_serialize_derive::BinarySerializable;
use quaternion::Quaternion;
use vecmath::Vector3;
pub trait BinarySerializable {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()>;
}
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum PegType {
Input = 1,
Output = 2,
}
pub type Int = i32;
pub type Float = f32;
pub type ComponentAddress = u32;
#[derive(BinarySerializable)]
pub struct Version {
pub major: Int,
pub minor: Int,
pub build: Int,
pub revision: Int,
}
impl Version {
pub fn new(major: Int, minor: Int, build: Int, revision: Int) -> Self {
Self {
major,
minor,
build,
revision,
}
}
}
#[derive(BinarySerializable)]
pub struct ModVersion {
pub id: String,
pub version: Version,
}
#[derive(BinarySerializable)]
pub struct Input {
circuit_state_id: Int,
}
#[derive(BinarySerializable)]
pub struct Output {
circuit_state_id: Int,
}
#[derive(BinarySerializable)]
pub struct ComponentIdMap {
pub numeric_id: i16,
pub text_id: String,
}
#[derive(BinarySerializable)]
pub struct PegAddress {
peg_type: PegType,
component_address: ComponentAddress,
index: Int,
}
#[derive(BinarySerializable)]
pub struct Component {
pub address: ComponentAddress,
pub parent: ComponentAddress,
pub numeric_id: u16,
pub position: Vector3<Int>,
pub rotation: Quaternion<Float>,
pub inputs: Vec<Input>,
pub outputs: Vec<Output>,
pub custom_data: Vec<u8>,
}
#[derive(BinarySerializable)]
pub struct Wire {
first_point: PegAddress,
second_point: PegAddress,
circuit_state_id: Int,
wire_rotation: Float,
}
impl<T: BinarySerializable> BinarySerializable for Vec<T> {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
writer.write_all(&(self.len() as Int).to_le_bytes())?;
for value in self {
value.write_to(writer)?;
}
return Ok(());
}
}
impl BinarySerializable for Vec<u8> {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
writer.write_all(&(self.len() as Int).to_le_bytes())?;
writer.write_all(&self)?;
return Ok(());
}
}
impl BinarySerializable for PegType {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
writer.write_all(&[*self as u8])
}
}
impl BinarySerializable for String {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
writer.write_all(&(self.len() as Int).to_le_bytes())?;
writer.write_all(self.as_bytes())?;
return Ok(());
}
}
impl BinarySerializable for Vector3<Int> {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
self[0].write_to(writer)?; // x
self[1].write_to(writer)?; // y
self[2].write_to(writer)?; // z
return Ok(());
}
}
impl BinarySerializable for Quaternion<Float> {
fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
self.1[0].write_to(writer)?; // x
self.1[1].write_to(writer)?; // y
self.1[2].write_to(writer)?; // z
self.0.write_to(writer)?; // w
return Ok(());
}
}
macro_rules! impl_binary_num {
($($t:ty),*) => {
$(impl BinarySerializable for $t {
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(&self.to_le_bytes())
}
})*
};
}
impl_binary_num!(i16, u16, i32, u32, f32);
Loading…
Cancel
Save