ufftools 0.1.0

reader/writer and inspect CLI for the UFF character package format. includes the uff decoder lib for use in other projects.
Documentation
use ufftools::*;

pub fn generate_fixture() -> UffPackage {
    let pkg = UffPackage {
        char_name: "Ryu".into(),
        floor_y: 12,
        animations: vec![
            UffAnimation {
                name: "idle".into(),
                default_fps: 12,
                loop_mode: LoopMode::Loop,
                pixel_flags: 0,
                sheet_w: 256,
                sheet_h: 128,
                frame_w: 64,
                frame_h: 128,
                floor_y_override: 0,
                sprite_table: vec![
                    SpriteEntry {
                        src_x: 0,
                        src_y: 0,
                        src_w: 0,
                        src_h: 0,
                        pivot_x: -32,
                        pivot_y: -64,
                        entry_flags: 0,
                        tag: 0,
                        duration_ms: 0,
                    },
                    SpriteEntry {
                        src_x: 64,
                        src_y: 0,
                        src_w: 0,
                        src_h: 0,
                        pivot_x: -32,
                        pivot_y: -64,
                        entry_flags: 0,
                        tag: 0,
                        duration_ms: 0,
                    },
                ],
                frames: vec![
                    HitboxFrame {
                        id: 0,
                        label: "start".into(),
                        program: "".into(),
                        tags: "".into(),
                        hitboxes: vec![Hitbox {
                            name: "hurtbox".into(),
                            box_type: BoxType::Hurt,
                            enabled: true,
                            knockback: false,
                            x: 8.0,
                            y: 0.0,
                            width: 48.0,
                            height: 120.0,
                            damage: 0,
                            hitstun: 0,
                            blockstun: 0,
                            knockback_angle: 0.0,
                            knockback_strength: 0.0,
                            rotation: 0.0,
                        }],
                        audio_cues: vec![],
                    },
                    HitboxFrame {
                        id: 1,
                        label: "".into(),
                        program: "LOO 0\nLOP".into(),
                        tags: "looping=true".into(),
                        hitboxes: vec![],
                        audio_cues: vec![],
                    },
                ],
                pixel_data: Some(vec![0u8; 64]),
            },
            UffAnimation {
                name: "punch".into(),
                default_fps: 24,
                loop_mode: LoopMode::Once,
                pixel_flags: 0,
                sheet_w: 256,
                sheet_h: 128,
                frame_w: 64,
                frame_h: 128,
                floor_y_override: 10,
                sprite_table: vec![
                    SpriteEntry {
                        src_x: 0,
                        src_y: 128,
                        src_w: 0,
                        src_h: 0,
                        pivot_x: -32,
                        pivot_y: -64,
                        entry_flags: 0,
                        tag: 1,
                        duration_ms: 41,
                    },
                    SpriteEntry {
                        src_x: 64,
                        src_y: 128,
                        src_w: 0,
                        src_h: 0,
                        pivot_x: -32,
                        pivot_y: -64,
                        entry_flags: 0,
                        tag: 1,
                        duration_ms: 83,
                    },
                    SpriteEntry {
                        src_x: 128,
                        src_y: 128,
                        src_w: 0,
                        src_h: 0,
                        pivot_x: -32,
                        pivot_y: -64,
                        entry_flags: 0,
                        tag: 1,
                        duration_ms: 41,
                    },
                ],
                frames: vec![
                    HitboxFrame {
                        id: 0,
                        label: "startup".into(),
                        program: "".into(),
                        tags: "".into(),
                        hitboxes: vec![Hitbox {
                            name: "hurtbox".into(),
                            box_type: BoxType::Hurt,
                            enabled: true,
                            knockback: false,
                            x: 8.0,
                            y: 0.0,
                            width: 48.0,
                            height: 120.0,
                            damage: 0,
                            hitstun: 0,
                            blockstun: 0,
                            knockback_angle: 0.0,
                            knockback_strength: 0.0,
                            rotation: 0.0,
                        }],
                        audio_cues: vec![AudioCue {
                            clip_id: "punch_whoosh".into(),
                            volume: 1.0,
                            pitch: 1.0,
                        }],
                    },
                    HitboxFrame {
                        id: 1,
                        label: "active".into(),
                        program: "".into(),
                        tags: "cancel_window=true".into(),
                        hitboxes: vec![
                            Hitbox {
                                name: "hurtbox".into(),
                                box_type: BoxType::Hurt,
                                enabled: true,
                                knockback: false,
                                x: 8.0,
                                y: 0.0,
                                width: 48.0,
                                height: 120.0,
                                damage: 0,
                                hitstun: 0,
                                blockstun: 0,
                                knockback_angle: 0.0,
                                knockback_strength: 0.0,
                                rotation: 0.0,
                            },
                            Hitbox {
                                name: "fist".into(),
                                box_type: BoxType::Attack,
                                enabled: true,
                                knockback: true,
                                x: 56.0,
                                y: 40.0,
                                width: 28.0,
                                height: 20.0,
                                damage: 60,
                                hitstun: 12,
                                blockstun: 8,
                                knockback_angle: 35.0,
                                knockback_strength: 4.5,
                                rotation: -10.0,
                            },
                        ],
                        audio_cues: vec![AudioCue {
                            clip_id: "punch_hit".into(),
                            volume: 0.9,
                            pitch: 1.1,
                        }],
                    },
                    HitboxFrame {
                        id: 2,
                        label: "recovery".into(),
                        program: "".into(),
                        tags: "".into(),
                        hitboxes: vec![Hitbox {
                            name: "hurtbox".into(),
                            box_type: BoxType::Hurt,
                            enabled: true,
                            knockback: false,
                            x: 8.0,
                            y: 0.0,
                            width: 48.0,
                            height: 120.0,
                            damage: 0,
                            hitstun: 0,
                            blockstun: 0,
                            knockback_angle: 0.0,
                            knockback_strength: 0.0,
                            rotation: 0.0,
                        }],
                        audio_cues: vec![],
                    },
                ],
                pixel_data: None,
            },
        ],
    };
    pkg
}