mod sm64;
pub use sm64::{SM64GameGenerator, SM64Game, GamePad, GameState, RngConfig};
pub mod buttons;
#[cfg(test)]
mod tests {
use anyhow::Error;
use crate::{GamePad, SM64GameGenerator, buttons};
use plotters::prelude::*;
fn visualize_positions(positions1: &Vec<[f32; 3]>, positions2: &Vec<[f32; 3]>) -> Result<(), Box<dyn std::error::Error>> {
let root = BitMapBackend::new("output.png", (640, 480)).into_drawing_area();
root.fill(&WHITE).unwrap();
let mut chart = ChartBuilder::on(&root)
.caption("Two Datasets Plot", ("sans-serif", 50).into_font())
.margin(5)
.x_label_area_size(30)
.y_label_area_size(30)
.build_cartesian_2d(-8000.0..8000.0, -8000.0..8000.0) .unwrap();
chart.configure_mesh().draw().unwrap();
let series1: Vec<(f64, f64)> = positions1.iter().map(|&[x, _, y]| (x.into(), y.into())).collect();
chart.draw_series(LineSeries::new(series1, &RED)).unwrap()
.label("Dataset 1")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));
let series2: Vec<(f64, f64)> = positions2.iter().map(|&[x, _, y]| (x.into(), y.into())).collect();
chart.draw_series(LineSeries::new(series2, &BLUE)).unwrap()
.label("Dataset 2")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &BLUE));
chart.configure_series_labels().border_style(&BLACK).draw().unwrap();
Ok(())
}
#[test]
fn no_rng() -> Result<(), Error> {
let game_gen = SM64GameGenerator::new(include_bytes!("../../baserom.us.z64").to_vec())?;
let mut game = game_gen.create_game()?;
let mut i = 0;
while i < 2000 {
let mut button: u16 = 0;
let stick_x: i8 = 0;
let mut stick_y: i8 = 0;
if (150 < i && i < 160) || (200 < i && i < 300) {
button = buttons::START_BUTTON;
}
if i > 300 {
stick_y = 80;
}
if i % 2 == 0 {
button = buttons::A_BUTTON;
}
let pad = GamePad::new(button, stick_x, stick_y);
game.step_game(pad)?;
let state = game.get_game_state()?;
println!("{}\n", state.to_string());
i += 1;
}
Ok(())
}
#[test]
fn yes_rng() -> Result<(), Error> {
let game_gen = SM64GameGenerator::new(include_bytes!("../../baserom.us.z64").to_vec())?;
let mut game = game_gen.create_game()?;
let seed = 22;
game.set_rng_seed(seed)?;
let mut i = 0;
while i < 2000 {
let mut button: u16 = 0;
let stick_x: i8 = 0;
let stick_y: i8 = 0;
if (150 < i && i < 160) || (200 < i && i < 300) {
button = buttons::START_BUTTON;
}
let mut pad = GamePad::new(button, stick_x, stick_y);
pad = game.rng_pad(pad)?;
game.step_game(pad)?;
print!("{:#?}\n", pad);
i += 1;
}
Ok(())
}
#[test]
fn mem_test() -> Result<(), Box<dyn std::error::Error>> {
let game_gen = SM64GameGenerator::new(include_bytes!("../../baserom.us.z64").to_vec())?;
let mut game = game_gen.create_game()?;
let mut game2 = game_gen.create_game()?;
let mut positions_list = Vec::new();
let mut positions_clone_list = Vec::new();
for i in 0..3000 { let mut button = 0;
let mut sticky = 0;
if (150 < i && i < 160) || (200 < i && i < 300) {
button = buttons::START_BUTTON;
}
if i > 300 {
sticky = 80;
}
if i % 2 == 0 {
button = buttons::A_BUTTON; }
let pad = GamePad::new(button, 0, sticky);
if i == 1760 {
game_gen.copy_to(&game, &mut game2)?; }
if i >= 1760 {
let mut button2 = 0;
if button2 % 8 == 0 {
button2 = buttons::A_BUTTON;
}
let pad2 = GamePad::new(button2, 40, 80);
game2.step_game(pad2)?;
let state2 = game2.get_game_state()?;
positions_clone_list.push(state2.pos);
}
game.step_game(pad)?;
let state = game.get_game_state()?;
positions_list.push(state.pos);
}
visualize_positions(&positions_list, &positions_clone_list)?;
Ok(())
}
}