From bef39f9b8b967cfa98866659e1edfd94e28668ca Mon Sep 17 00:00:00 2001 From: Max Bradbury Date: Sun, 12 Apr 2020 17:13:08 +0100 Subject: [PATCH] allow public uses of structs; add sample program --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++---- src/avatar.rs | 9 ++++----- src/bin/smiley.rs | 32 +++++++++++++++++++++++++++++++ src/colour.rs | 6 +++--- src/dialogue.rs | 4 ++-- src/exit.rs | 9 ++++----- src/game.rs | 26 ++++++++++++------------- src/image.rs | 6 +++--- src/item.rs | 8 ++++---- src/mock.rs | 4 ++-- src/palette.rs | 6 +++--- src/position.rs | 4 ++-- src/room.rs | 14 +++++++------- src/sprite.rs | 12 ++++++------ src/variable.rs | 4 ++-- 15 files changed, 132 insertions(+), 61 deletions(-) create mode 100644 src/bin/smiley.rs diff --git a/README.md b/README.md index 8ecd9da..0da0ef6 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,51 @@ a library for parsing Bitsy game data. the version number follows Bitsy itself, so version 0.65.* targets Bitsy 6.5. +## how to use + +this sample program converts the player avatar to a smiley face. +```rust +extern crate bitsy_parser; +use std::{env, fs}; +use bitsy_parser::game::Game; +use bitsy_parser::image::Image; + +/// replaces the player avatar with a smiley face. +fn main() { + let input_file = env::args().nth(1) + .expect("No game data specified. Usage: `invert infile outfile`"); + let output_file = env::args().nth(2) + .expect("No game data specified. Usage: `invert infile outfile`"); + + let mut game = Game::from(fs::read_to_string(input_file).unwrap()); + + game.avatar.animation_frames = vec![ + Image { + pixels: vec![ + 0,0,1,1,1,1,0,0, + 0,1,1,1,1,1,1,0, + 1,1,0,1,1,0,1,1, + 1,1,0,1,1,0,1,1, + 1,1,1,1,1,1,1,1, + 1,1,0,1,1,0,1,1, + 0,1,1,0,0,1,1,0, + 0,0,1,1,1,1,0,0, + ] + } + ]; + + fs::write(output_file, &game.to_string()) + .expect("Failed to write to output file"); +} +``` + +some more practical uses would be things like: + +* remove duplicate tiles +* merge two Bitsy games together +* programmatically create Bitsy games +* a Bitsy game editor + ## todo ### failing tests @@ -13,7 +58,3 @@ test_room_from_string shows an unexpected ordering for the items in the output o ### tidy up * refactor the more shonky bits to idiomatic rust - -### documentation - -examples of use cases (dedupe tiles, merge games, etc.) diff --git a/src/avatar.rs b/src/avatar.rs index 01c6d0f..eb2c3d5 100644 --- a/src/avatar.rs +++ b/src/avatar.rs @@ -1,12 +1,11 @@ -use crate::{AnimationFrames, Image, Position}; -use crate::mock; +use crate::{AnimationFrames, Image, mock, Position}; /// avatar is a "sprite" in the game data but with a specific id #[derive(Debug, Eq, PartialEq)] pub struct Avatar { - pub(crate) animation_frames: Vec, - pub(crate) room: String, /// room id - pub(crate) position: Position, + pub animation_frames: Vec, + pub room: String, /// room id + pub position: Position, } impl From for Avatar { diff --git a/src/bin/smiley.rs b/src/bin/smiley.rs new file mode 100644 index 0000000..827d1e2 --- /dev/null +++ b/src/bin/smiley.rs @@ -0,0 +1,32 @@ +extern crate bitsy_parser; +use std::{env, fs}; +use bitsy_parser::game::Game; +use bitsy_parser::image::Image; + +/// replaces the player avatar with a smiley face. +fn main() { + let input_file = env::args().nth(1) + .expect("No game data specified. Usage: `invert infile outfile`"); + let output_file = env::args().nth(2) + .expect("No game data specified. Usage: `invert infile outfile`"); + + let mut game = Game::from(fs::read_to_string(input_file).unwrap()); + + game.avatar.animation_frames = vec![ + Image { + pixels: vec![ + 0,0,1,1,1,1,0,0, + 0,1,1,1,1,1,1,0, + 1,1,0,1,1,0,1,1, + 1,1,0,1,1,0,1,1, + 1,1,1,1,1,1,1,1, + 1,1,0,1,1,0,1,1, + 0,1,1,0,0,1,1,0, + 0,0,1,1,1,1,0,0, + ] + } + ]; + + fs::write(output_file, &game.to_string()) + .expect("Failed to write to output file"); +} diff --git a/src/colour.rs b/src/colour.rs index 5690ca9..90b631e 100644 --- a/src/colour.rs +++ b/src/colour.rs @@ -1,8 +1,8 @@ #[derive(Debug, Eq, PartialEq)] pub struct Colour { - pub(crate) red: u8, - pub(crate) green: u8, - pub(crate) blue: u8, + pub red: u8, + pub green: u8, + pub blue: u8, } impl From for Colour { diff --git a/src/dialogue.rs b/src/dialogue.rs index 12a0096..8bee8d3 100644 --- a/src/dialogue.rs +++ b/src/dialogue.rs @@ -1,7 +1,7 @@ #[derive(Debug, Eq, PartialEq)] pub struct Dialogue { - pub(crate) id: String, - pub(crate) contents: String, + pub id: String, + pub contents: String, } impl From for Dialogue { diff --git a/src/exit.rs b/src/exit.rs index 9de25a9..5ed5b6d 100644 --- a/src/exit.rs +++ b/src/exit.rs @@ -1,8 +1,7 @@ use crate::Position; -use std::iter::Enumerate; #[derive(Debug, Eq, PartialEq)] -pub(crate) enum Transition { +pub enum Transition { None, FadeToWhite, FadeToBlack, @@ -49,9 +48,9 @@ impl ToString for Transition { #[derive(Debug, Eq, PartialEq)] pub struct Exit { /// destination - pub(crate) room: String, /// id - pub(crate) position: Position, - pub(crate) effect: Transition, + pub room: String, /// id + pub position: Position, + pub effect: Transition, } impl From for Exit { diff --git a/src/game.rs b/src/game.rs index 7386b75..01a8cae 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,19 +1,19 @@ use crate::{Avatar, Dialogue, Ending, Item, Palette, Room, Sprite, Tile, Variable, mock}; #[derive(Debug, PartialEq)] -pub(crate) struct Game { - pub(crate) name: String, - pub(crate) version: f64, - pub(crate) room_format: u8, - pub(crate) palettes: Vec, - pub(crate) rooms: Vec, - pub(crate) tiles: Vec, - pub(crate) avatar: Avatar, - pub(crate) sprites: Vec, - pub(crate) items: Vec, - pub(crate) dialogues: Vec, - pub(crate) endings: Vec, - pub(crate) variables: Vec, +pub struct Game { + pub name: String, + pub version: f64, + pub room_format: u8, + pub palettes: Vec, + pub rooms: Vec, + pub tiles: Vec, + pub avatar: Avatar, + pub sprites: Vec, + pub items: Vec, + pub dialogues: Vec, + pub endings: Vec, + pub variables: Vec, } impl From for Game { diff --git a/src/image.rs b/src/image.rs index 152834f..f64ea52 100644 --- a/src/image.rs +++ b/src/image.rs @@ -2,7 +2,7 @@ use crate::mock; #[derive(Debug, Eq, PartialEq)] pub struct Image { - pub(crate) pixels: Vec, // 64 for SD, 256 for HD + pub pixels: Vec, // 64 for SD, 256 for HD } impl From for Image { @@ -12,8 +12,8 @@ impl From for Image { let pixels: Vec<&str> = string.split("").collect(); // the above seems to add an extra "" at the start and end of the vec, so strip them below let pixels = &pixels[1..(pixels.len() - 1)]; - let pixels: Vec = pixels.iter().map(|&pixel| { - pixel.parse::().unwrap() + let pixels: Vec = pixels.iter().map(|&pixel| { + pixel.parse::().unwrap() }).collect(); Image { pixels } diff --git a/src/item.rs b/src/item.rs index 1374db0..c92ecaf 100644 --- a/src/item.rs +++ b/src/item.rs @@ -2,10 +2,10 @@ use crate::{AnimationFrames, Image, mock}; #[derive(Debug, Eq, PartialEq)] pub struct Item { - pub(crate) id: String, - pub(crate) animation_frames: Vec, - pub(crate) name: Option, - pub(crate) dialogue: Option, // dialogue id + pub id: String, + pub animation_frames: Vec, + pub name: Option, + pub dialogue: Option, // dialogue id } impl From for Item { diff --git a/src/mock.rs b/src/mock.rs index f082eab..ed589a0 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -67,7 +67,7 @@ pub fn avatar() -> Avatar { } } -pub(crate) fn sprite() -> Sprite { +pub fn sprite() -> Sprite { Sprite { id: "a".to_string(), name: Some("hatch".to_string()), @@ -158,7 +158,7 @@ pub fn room() -> Room { } } -pub(crate) fn game_default() -> Game { +pub fn game_default() -> Game { Game { name: "Write your game's title here".to_string(), version: 6.5, diff --git a/src/palette.rs b/src/palette.rs index f454d79..1fbf9f4 100644 --- a/src/palette.rs +++ b/src/palette.rs @@ -2,9 +2,9 @@ use crate::colour::Colour; #[derive(Debug, Eq, PartialEq)] pub struct Palette { - pub(crate) id: String, // base36 string (why??) - pub(crate) name: Option, - pub(crate) colours: Vec, + pub id: String, // base36 string (why??) + pub name: Option, + pub colours: Vec, } impl From for Palette { diff --git a/src/position.rs b/src/position.rs index f22719a..1b946c9 100644 --- a/src/position.rs +++ b/src/position.rs @@ -1,7 +1,7 @@ #[derive(Debug, Eq, PartialEq)] pub struct Position { - pub(crate) x: u8, - pub(crate) y: u8, + pub x: u8, + pub y: u8, } impl From for Position { diff --git a/src/room.rs b/src/room.rs index 041bc9d..3f6a423 100644 --- a/src/room.rs +++ b/src/room.rs @@ -2,13 +2,13 @@ use crate::{Exit, ExitInstance, Instance, mock, Position}; #[derive(Debug, Eq, PartialEq)] pub struct Room { - pub(crate) id: String, - pub(crate) palette: String, // id - pub(crate) name: Option, - pub(crate) tiles: Vec, // tile ids - pub(crate) items: Vec, - pub(crate) exits: Vec, - pub(crate) endings: Vec, + pub id: String, + pub palette: String, // id + pub name: Option, + pub tiles: Vec, // tile ids + pub items: Vec, + pub exits: Vec, + pub endings: Vec, } impl From for Room { diff --git a/src/sprite.rs b/src/sprite.rs index 2aedeef..c7ee46d 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -2,12 +2,12 @@ use crate::{AnimationFrames, Image, Position, mock}; #[derive(Debug, Eq, PartialEq)] pub struct Sprite { - pub(crate) id: String, // lowercase base36 - pub(crate) name: Option, - pub(crate) animation_frames: Vec, - pub(crate) dialogue: Option, /// dialogue id - pub(crate) room: String, /// room id - pub(crate) position: Position, + pub id: String, // lowercase base36 + pub name: Option, + pub animation_frames: Vec, + pub dialogue: Option, /// dialogue id + pub room: String, /// room id + pub position: Position, } impl From for Sprite { diff --git a/src/variable.rs b/src/variable.rs index 9916f64..4fd7d58 100644 --- a/src/variable.rs +++ b/src/variable.rs @@ -1,7 +1,7 @@ #[derive(Debug, Eq, PartialEq)] pub struct Variable { - pub(crate) id: String, - pub(crate) initial_value: String, + pub id: String, + pub initial_value: String, } impl From for Variable {