allow public uses of structs; add sample program

This commit is contained in:
Max Bradbury 2020-04-12 17:13:08 +01:00
parent fd4a682ade
commit bef39f9b8b
15 changed files with 132 additions and 61 deletions

View File

@ -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. 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 ## todo
### failing tests ### failing tests
@ -13,7 +58,3 @@ test_room_from_string shows an unexpected ordering for the items in the output o
### tidy up ### tidy up
* refactor the more shonky bits to idiomatic rust * refactor the more shonky bits to idiomatic rust
### documentation
examples of use cases (dedupe tiles, merge games, etc.)

View File

@ -1,12 +1,11 @@
use crate::{AnimationFrames, Image, Position}; use crate::{AnimationFrames, Image, mock, Position};
use crate::mock;
/// avatar is a "sprite" in the game data but with a specific id /// avatar is a "sprite" in the game data but with a specific id
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Avatar { pub struct Avatar {
pub(crate) animation_frames: Vec<Image>, pub animation_frames: Vec<Image>,
pub(crate) room: String, /// room id pub room: String, /// room id
pub(crate) position: Position, pub position: Position,
} }
impl From<String> for Avatar { impl From<String> for Avatar {

32
src/bin/smiley.rs Normal file
View File

@ -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");
}

View File

@ -1,8 +1,8 @@
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Colour { pub struct Colour {
pub(crate) red: u8, pub red: u8,
pub(crate) green: u8, pub green: u8,
pub(crate) blue: u8, pub blue: u8,
} }
impl From<String> for Colour { impl From<String> for Colour {

View File

@ -1,7 +1,7 @@
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Dialogue { pub struct Dialogue {
pub(crate) id: String, pub id: String,
pub(crate) contents: String, pub contents: String,
} }
impl From<String> for Dialogue { impl From<String> for Dialogue {

View File

@ -1,8 +1,7 @@
use crate::Position; use crate::Position;
use std::iter::Enumerate;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub(crate) enum Transition { pub enum Transition {
None, None,
FadeToWhite, FadeToWhite,
FadeToBlack, FadeToBlack,
@ -49,9 +48,9 @@ impl ToString for Transition {
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Exit { pub struct Exit {
/// destination /// destination
pub(crate) room: String, /// id pub room: String, /// id
pub(crate) position: Position, pub position: Position,
pub(crate) effect: Transition, pub effect: Transition,
} }
impl From<String> for Exit { impl From<String> for Exit {

View File

@ -1,19 +1,19 @@
use crate::{Avatar, Dialogue, Ending, Item, Palette, Room, Sprite, Tile, Variable, mock}; use crate::{Avatar, Dialogue, Ending, Item, Palette, Room, Sprite, Tile, Variable, mock};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub(crate) struct Game { pub struct Game {
pub(crate) name: String, pub name: String,
pub(crate) version: f64, pub version: f64,
pub(crate) room_format: u8, pub room_format: u8,
pub(crate) palettes: Vec<Palette>, pub palettes: Vec<Palette>,
pub(crate) rooms: Vec<Room>, pub rooms: Vec<Room>,
pub(crate) tiles: Vec<Tile>, pub tiles: Vec<Tile>,
pub(crate) avatar: Avatar, pub avatar: Avatar,
pub(crate) sprites: Vec<Sprite>, pub sprites: Vec<Sprite>,
pub(crate) items: Vec<Item>, pub items: Vec<Item>,
pub(crate) dialogues: Vec<Dialogue>, pub dialogues: Vec<Dialogue>,
pub(crate) endings: Vec<Ending>, pub endings: Vec<Ending>,
pub(crate) variables: Vec<Variable>, pub variables: Vec<Variable>,
} }
impl From<String> for Game { impl From<String> for Game {

View File

@ -2,7 +2,7 @@ use crate::mock;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Image { pub struct Image {
pub(crate) pixels: Vec<u8>, // 64 for SD, 256 for HD pub pixels: Vec<u32>, // 64 for SD, 256 for HD
} }
impl From<String> for Image { impl From<String> for Image {
@ -12,8 +12,8 @@ impl From<String> for Image {
let pixels: Vec<&str> = string.split("").collect(); 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 // 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 = &pixels[1..(pixels.len() - 1)];
let pixels: Vec<u8> = pixels.iter().map(|&pixel| { let pixels: Vec<u32> = pixels.iter().map(|&pixel| {
pixel.parse::<u8>().unwrap() pixel.parse::<u32>().unwrap()
}).collect(); }).collect();
Image { pixels } Image { pixels }

View File

@ -2,10 +2,10 @@ use crate::{AnimationFrames, Image, mock};
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Item { pub struct Item {
pub(crate) id: String, pub id: String,
pub(crate) animation_frames: Vec<Image>, pub animation_frames: Vec<Image>,
pub(crate) name: Option<String>, pub name: Option<String>,
pub(crate) dialogue: Option<String>, // dialogue id pub dialogue: Option<String>, // dialogue id
} }
impl From<String> for Item { impl From<String> for Item {

View File

@ -67,7 +67,7 @@ pub fn avatar() -> Avatar {
} }
} }
pub(crate) fn sprite() -> Sprite { pub fn sprite() -> Sprite {
Sprite { Sprite {
id: "a".to_string(), id: "a".to_string(),
name: Some("hatch".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 { Game {
name: "Write your game's title here".to_string(), name: "Write your game's title here".to_string(),
version: 6.5, version: 6.5,

View File

@ -2,9 +2,9 @@ use crate::colour::Colour;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Palette { pub struct Palette {
pub(crate) id: String, // base36 string (why??) pub id: String, // base36 string (why??)
pub(crate) name: Option<String>, pub name: Option<String>,
pub(crate) colours: Vec<Colour>, pub colours: Vec<Colour>,
} }
impl From<String> for Palette { impl From<String> for Palette {

View File

@ -1,7 +1,7 @@
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Position { pub struct Position {
pub(crate) x: u8, pub x: u8,
pub(crate) y: u8, pub y: u8,
} }
impl From<String> for Position { impl From<String> for Position {

View File

@ -2,13 +2,13 @@ use crate::{Exit, ExitInstance, Instance, mock, Position};
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Room { pub struct Room {
pub(crate) id: String, pub id: String,
pub(crate) palette: String, // id pub palette: String, // id
pub(crate) name: Option<String>, pub name: Option<String>,
pub(crate) tiles: Vec<String>, // tile ids pub tiles: Vec<String>, // tile ids
pub(crate) items: Vec<Instance>, pub items: Vec<Instance>,
pub(crate) exits: Vec<ExitInstance>, pub exits: Vec<ExitInstance>,
pub(crate) endings: Vec<Instance>, pub endings: Vec<Instance>,
} }
impl From<String> for Room { impl From<String> for Room {

View File

@ -2,12 +2,12 @@ use crate::{AnimationFrames, Image, Position, mock};
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Sprite { pub struct Sprite {
pub(crate) id: String, // lowercase base36 pub id: String, // lowercase base36
pub(crate) name: Option<String>, pub name: Option<String>,
pub(crate) animation_frames: Vec<Image>, pub animation_frames: Vec<Image>,
pub(crate) dialogue: Option<String>, /// dialogue id pub dialogue: Option<String>, /// dialogue id
pub(crate) room: String, /// room id pub room: String, /// room id
pub(crate) position: Position, pub position: Position,
} }
impl From<String> for Sprite { impl From<String> for Sprite {

View File

@ -1,7 +1,7 @@
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct Variable { pub struct Variable {
pub(crate) id: String, pub id: String,
pub(crate) initial_value: String, pub initial_value: String,
} }
impl From<String> for Variable { impl From<String> for Variable {