blotter.rs/src/lib.rs

132 lines
3 KiB
Rust
Raw Normal View History

2021-06-28 23:56:19 -05:00
use declio::ctx::Len;
use declio::util::{magic_bytes, zero_one, LittleEndian};
2021-06-28 23:56:19 -05:00
use declio::{Decode, Encode};
use std::convert::TryInto;
type ComponentId = LittleEndian<u16>;
type ComponentAddress = LittleEndian<u32>;
type Int = LittleEndian<i32>;
type Float = LittleEndian<f32>;
2021-07-08 12:45:27 -05:00
type Version = [Int; 4];
2021-06-28 23:56:19 -05:00
#[derive(Debug, Clone, Copy, PartialEq, Encode, Decode)]
#[declio(id_type = "u8")]
enum SaveType {
#[declio(id = "1")]
World,
#[declio(id = "2")]
Subassembly,
}
2021-06-28 23:56:19 -05:00
#[derive(Debug, Encode, Decode)]
pub struct BlotterFile {
header: Header,
save_version: u8,
2021-07-08 12:45:27 -05:00
game_version: Version,
save_type: SaveType,
2021-06-28 23:56:19 -05:00
components_len: Int,
wires_len: Int,
2021-07-08 12:45:27 -05:00
mods_len: Int,
#[declio(ctx = "Len(mods_len.0.try_into()?)")]
mods: Vec<Mod>,
2021-06-28 23:56:19 -05:00
component_ids_len: Int,
#[declio(ctx = "Len(component_ids_len.0.try_into()?)")]
component_ids: Vec<ComponentIdMapping>,
#[declio(ctx = "Len(components_len.0.try_into()?)")]
components: Vec<Component>,
#[declio(ctx = "Len(wires_len.0.try_into()?)")]
wires: Vec<Wire>,
#[declio(ctx = "*save_type")]
circuit_states: CircuitStates,
footer: Footer,
}
magic_bytes! {
#[derive(Debug)]
2021-06-29 21:30:55 -05:00
Header(b"Logic World save");
2021-06-28 23:56:19 -05:00
#[derive(Debug)]
Footer(b"redstone sux lol");
}
#[derive(Debug, Encode, Decode)]
struct Text {
len: Int,
#[declio(with = "declio::util::utf8", ctx = "Len(len.0.try_into()?)")]
value: String,
}
2021-07-08 12:45:27 -05:00
#[derive(Debug, Encode, Decode)]
struct Mod {
mod_id: Text,
version: Version,
}
2021-06-28 23:56:19 -05:00
#[derive(Debug, Encode, Decode)]
struct ComponentIdMapping {
numeric_id: ComponentId,
text_id: Text,
}
#[derive(Debug, Encode, Decode)]
struct Input {
circuit_state_id: Int,
}
#[derive(Debug, Encode, Decode)]
struct Output {
circuit_state_id: Int,
}
#[derive(Debug, Encode, Decode)]
struct Component {
address: ComponentAddress,
parent: ComponentAddress,
type_id: ComponentId,
position: [Float; 3],
rotation: [Float; 4],
2021-07-08 12:45:27 -05:00
inputs_len: Int,
#[declio(ctx = "Len(inputs_len.0.try_into()?)")]
2021-06-28 23:56:19 -05:00
inputs: Vec<Input>,
2021-07-08 12:45:27 -05:00
outputs_len: Int,
#[declio(ctx = "Len(outputs_len.0.try_into()?)")]
2021-06-28 23:56:19 -05:00
outputs: Vec<Output>,
custom_data_len: Int,
#[declio(skip_if = "custom_data_len.0 == -1")]
#[declio(ctx = "Len(custom_data_len.0.try_into()?)")]
custom_data: Option<Vec<u8>>,
2021-07-08 12:45:27 -05:00
}
2021-06-28 23:56:19 -05:00
#[derive(Debug, Encode, Decode)]
struct PegAddress {
#[declio(with = "zero_one")]
is_input: bool,
2021-06-28 23:56:19 -05:00
component: ComponentAddress,
2021-07-08 12:45:27 -05:00
index: Int,
2021-06-28 23:56:19 -05:00
}
#[derive(Debug, Encode, Decode)]
struct Wire {
peg_1: PegAddress,
peg_2: PegAddress,
circuit_state_id: Int,
rotation: Float,
}
#[derive(Debug, Encode, Decode)]
#[declio(ctx = "save_type: SaveType", id_expr = "save_type")]
2021-06-28 23:56:19 -05:00
enum CircuitStates {
#[declio(id = "SaveType::World")]
2021-06-28 23:56:19 -05:00
WorldFormat {
len: Int,
#[declio(ctx = "Len(len.0.try_into()?)")]
circuit_states: Vec<u8>,
},
#[declio(id = "SaveType::Subassembly")]
2021-06-28 23:56:19 -05:00
SubassemblyFormat {
len: Int,
#[declio(ctx = "Len(len.0.try_into()?)")]
on_states: Vec<Int>,
},
}