Peppi
Peppi is a Rust parser for .slp game replay files for Super Smash Brothers Melee for the Nintendo GameCube. These replays are generated by Jas Laferriere's Slippi recording code, which runs on a Wii or the Dolphin emulator.
Peppi is fairly full-featured already, but still under active development. APIs are still subject to breaking change until version 1.0 is released.
Installation
In your Cargo.toml:
[dependencies]
peppi = "2.0.0-alpha.1"
Usage
One-shot parsing just requires calling peppi::game.
use std::{fs, io};
use ssbm_data::action_state::Common::{self, *};
fn main() {
let mut r = io::BufReader::new(fs::File::open("game.slp").unwrap());
let game = peppi::game(&mut r, None).unwrap();
println!("{:#?}", game);
let mut is_dead: Vec<_> = game.frames.ports.iter().map(|_| false).collect();
for frame_idx in 0..game.frames.id.len() {
for (port_idx, port_data) in game.frames.ports.iter().enumerate() {
match port_data
.leader
.post
.state
.get(frame_idx)
.and_then(|s| Common::try_from(s).ok())
{
Some(DeadDown)
| Some(DeadLeft)
| Some(DeadRight)
| Some(DeadUp)
| Some(DeadUpStar)
| Some(DeadUpStarIce)
| Some(DeadUpFall)
| Some(DeadUpFallHitCamera)
| Some(DeadUpFallHitCameraFlat)
| Some(DeadUpFallIce)
| Some(DeadUpFallHitCameraIce) => {
if !is_dead[port_idx] {
is_dead[port_idx] = true;
println!(
"{} died on frame {}",
game.start.players[port_idx].port,
game.frames.id.get(frame_idx).unwrap(),
)
}
}
_ => is_dead[port_idx] = false,
}
}
}
}
For real-time parsing, you can "drive" things yourself:
use std::fs;
use std::io::{BufReader, Read};
use byteorder::ReadBytesExt;
use peppi::serde::de;
fn main() {
let mut r = BufReader::new(fs::File::open("v3.12.slp").unwrap());
let size = de::parse_header(&mut r, None).unwrap() as usize;
let mut state = de::parse_start(&mut r, None).unwrap();
while de::parse_event(&mut r, &mut state, None).unwrap() != de::Event::GameEnd as u8
&& state.bytes_read() < size
{
println!(
"current frame number: {:?}",
state.frames().id.iter().last()
);
}
if r.read_u8().unwrap() == 0x55 {
de::parse_metadata(r.by_ref(), &mut state, None).unwrap();
}
}
Inspector
⚠ The slp tool has moved to the peppi-slp crate.