survivor

graphical action game for the linux terminal
git clone https://git.ce9e.org/survivor.git

commit
23ec563928c1b01107aaa54592f26bd7f2f07111
parent
697e1d734fd02235720562d7bfae79bcd3bf0675
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-02-19 11:02
convert ppm2rust to rust macros

Diffstat

M .gitignore 2 +-
M Makefile 12 ++++--------
A ppm.rs 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
D ppm2rust.py 34 ----------------------------------
A src/sprites.rs 22 ++++++++++++++++++++++

5 files changed, 82 insertions, 43 deletions


diff --git a/.gitignore b/.gitignore

@@ -1,4 +1,4 @@
    1     1 /target
    2     2 survivor
    3     3 *.rlib
    4    -1 sprites.rs
   -1     4 *.so

diff --git a/Makefile b/Makefile

@@ -1,13 +1,9 @@
    1    -1 survivor: src/main.rs src/input.rs src/random.rs src/term.rs src/enemies.rs src/sprites.rs liblibc.rlib
    2    -1 	rustc -O --crate-name $@ --extern libc=liblibc.rlib --extern sprites=libsprites.rlib src/main.rs
   -1     1 survivor: src/main.rs src/input.rs src/random.rs src/term.rs src/enemies.rs src/sprites.rs liblibc.rlib libppm.so
   -1     2 	rustc -O --crate-name $@ --extern libc=liblibc.rlib --extern ppm=libppm.so src/main.rs
    3     3 	strip $@
    4     4 
    5     5 lib%.rlib: src/%.rs
    6     6 	rustc $< --crate-type lib
    7     7 
    8    -1 src/sprites.rs: ppm/*.ppm ppm2rust.py
    9    -1 	echo 'pub const HEIGHT: usize = 24;' > $@
   10    -1 	echo 'pub const WIDTH: usize = 18;' >> $@
   11    -1 	echo 'pub type Sprite = [[[u8; 3]; WIDTH]; HEIGHT];' >> $@
   12    -1 	echo >> $@
   13    -1 	find ppm/ -type f | while read l; do python ppm2rust.py "$$l"; done >> $@
   -1     8 libppm.so: ppm.rs
   -1     9 	rustc ppm.rs --crate-type proc-macro

diff --git a/ppm.rs b/ppm.rs

@@ -0,0 +1,55 @@
   -1     1 use std::fs::File;
   -1     2 use std::io::BufRead;
   -1     3 use std::io::BufReader;
   -1     4 use std::iter::FromIterator;
   -1     5 
   -1     6 extern crate proc_macro;
   -1     7 use proc_macro::{Delimiter, Group, Literal, Punct, Spacing, TokenStream, TokenTree};
   -1     8 
   -1     9 const WIDTH: usize = 18;
   -1    10 const HEIGHT: usize = 24;
   -1    11 
   -1    12 fn comma() -> TokenTree {
   -1    13     return TokenTree::Punct(Punct::new(',', Spacing::Alone));
   -1    14 }
   -1    15 
   -1    16 fn group(items: Vec<TokenTree>) -> TokenTree {
   -1    17     return TokenTree::Group(Group::new(
   -1    18         Delimiter::Bracket,
   -1    19         TokenStream::from_iter(items.into_iter()),
   -1    20     ));
   -1    21 }
   -1    22 
   -1    23 #[proc_macro]
   -1    24 pub fn include_ppm(input: TokenStream) -> TokenStream {
   -1    25     let s = input.into_iter().next().unwrap().to_string();
   -1    26     let name = s.strip_prefix('"').unwrap().strip_suffix('"').unwrap();
   -1    27     let p = format!("ppm/{}.ppm", name);
   -1    28 
   -1    29     let path = std::path::Path::new(&p);
   -1    30     let file = File::open(path).unwrap();
   -1    31     let mut lines = BufReader::new(file).lines().map(|l| l.unwrap());
   -1    32 
   -1    33     assert_eq!(lines.next().unwrap(), "P3");
   -1    34     assert!(lines.next().unwrap().starts_with('#'));
   -1    35     assert_eq!(lines.next().unwrap(), format!("{} {}", WIDTH, HEIGHT));
   -1    36     assert_eq!(lines.next().unwrap(), "255");
   -1    37 
   -1    38     let mut rows = vec![];
   -1    39     for _ in 0..HEIGHT {
   -1    40         let mut row = vec![];
   -1    41         for _ in 0..WIDTH {
   -1    42             let mut color = vec![];
   -1    43             for _ in 0..3 {
   -1    44                 let value = lines.next().unwrap().parse::<u8>().unwrap();
   -1    45                 color.push(TokenTree::Literal(Literal::u8_unsuffixed(value)));
   -1    46                 color.push(comma());
   -1    47             }
   -1    48             row.push(group(color));
   -1    49             row.push(comma());
   -1    50         }
   -1    51         rows.push(group(row));
   -1    52         rows.push(comma());
   -1    53     }
   -1    54     return TokenStream::from(group(rows));
   -1    55 }

diff --git a/ppm2rust.py b/ppm2rust.py

@@ -1,34 +0,0 @@
    1    -1 import os
    2    -1 import sys
    3    -1 
    4    -1 WIDTH = 18
    5    -1 HEIGHT = 24
    6    -1 
    7    -1 def _next(i):
    8    -1 	return next(i).rstrip()
    9    -1 
   10    -1 
   11    -1 name = os.path.basename(sys.argv[1]).rsplit('.', 1)[0].upper()
   12    -1 
   13    -1 with open(sys.argv[1]) as fh:
   14    -1 	lines = iter(fh)
   15    -1 	assert _next(lines) == 'P3'
   16    -1 	assert _next(lines).startswith('#')
   17    -1 	assert _next(lines) == f'{WIDTH} {HEIGHT}'
   18    -1 	assert _next(lines) == '255'
   19    -1 	print(f'pub const {name}: Sprite = [')
   20    -1 	first = True
   21    -1 	for y in range(HEIGHT):
   22    -1 		if first:
   23    -1 			print('    [')
   24    -1 			first = False
   25    -1 		else:
   26    -1 			print('    ], [')
   27    -1 		for x in range(WIDTH):
   28    -1 			r = int(_next(lines), 10)
   29    -1 			g = int(_next(lines), 10)
   30    -1 			b = int(_next(lines), 10)
   31    -1 			print(f'        [{r}, {g}, {b}],')
   32    -1 	print('    ]')
   33    -1 	print('];')
   34    -1 	print()

diff --git a/src/sprites.rs b/src/sprites.rs

@@ -0,0 +1,22 @@
   -1     1 extern crate ppm;
   -1     2 
   -1     3 pub const HEIGHT: usize = 24;
   -1     4 pub const WIDTH: usize = 18;
   -1     5 pub type Sprite = [[[u8; 3]; WIDTH]; HEIGHT];
   -1     6 
   -1     7 pub const HERO: Sprite = ppm::include_ppm!("hero");
   -1     8 pub const DIAMOND: Sprite = ppm::include_ppm!("diamond");
   -1     9 
   -1    10 pub const BAT: Sprite = ppm::include_ppm!("bat");
   -1    11 pub const BAT2: Sprite = ppm::include_ppm!("bat2");
   -1    12 pub const CRAWL: Sprite = ppm::include_ppm!("crawl");
   -1    13 pub const EYE: Sprite = ppm::include_ppm!("eye");
   -1    14 pub const GHOST: Sprite = ppm::include_ppm!("ghost");
   -1    15 pub const HOOD: Sprite = ppm::include_ppm!("hood");
   -1    16 pub const MUMMY: Sprite = ppm::include_ppm!("mummy");
   -1    17 pub const PLANTGUY: Sprite = ppm::include_ppm!("plantguy");
   -1    18 pub const SHADOW: Sprite = ppm::include_ppm!("shadow");
   -1    19 pub const SKELETON: Sprite = ppm::include_ppm!("skeleton");
   -1    20 pub const SKELETON2: Sprite = ppm::include_ppm!("skeleton2");
   -1    21 pub const SNAKE: Sprite = ppm::include_ppm!("snake");
   -1    22 pub const ZOMBIE: Sprite = ppm::include_ppm!("zombie");