2021-06-28 23:56:19 -05:00
|
|
|
use declio::ctx::Len;
|
2021-06-29 00:21:18 -05:00
|
|
|
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
|
|
|
|
2021-06-29 00:21:18 -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,
|
2021-06-29 00:21:18 -05:00
|
|
|
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,
|
2021-07-08 12:52:35 -05:00
|
|
|
#[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 {
|
2021-06-29 00:21:18 -05:00
|
|
|
#[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)]
|
2021-06-29 00:21:18 -05:00
|
|
|
#[declio(ctx = "save_type: SaveType", id_expr = "save_type")]
|
2021-06-28 23:56:19 -05:00
|
|
|
enum CircuitStates {
|
2021-06-29 00:21:18 -05:00
|
|
|
#[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>,
|
|
|
|
|
},
|
2021-06-29 00:21:18 -05:00
|
|
|
#[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>,
|
|
|
|
|
},
|
|
|
|
|
}
|