1mod sm64;
2pub use sm64::{SM64GameGenerator, SM64Game, GamePad, GameState, RngConfig};
3pub mod buttons;
4
5
6#[cfg(test)]
7mod tests {
8 use anyhow::Error;
9 use crate::{GamePad, SM64GameGenerator, buttons};
10 use plotters::prelude::*;
11
12 fn visualize_positions(positions1: &Vec<[f32; 3]>, positions2: &Vec<[f32; 3]>) -> Result<(), Box<dyn std::error::Error>> {
13
14 let root = BitMapBackend::new("output.png", (640, 480)).into_drawing_area();
16 root.fill(&WHITE).unwrap();
17
18 let mut chart = ChartBuilder::on(&root)
20 .caption("Two Datasets Plot", ("sans-serif", 50).into_font())
21 .margin(5)
22 .x_label_area_size(30)
23 .y_label_area_size(30)
24 .build_cartesian_2d(-8000.0..8000.0, -8000.0..8000.0) .unwrap();
26
27 chart.configure_mesh().draw().unwrap();
29
30 let series1: Vec<(f64, f64)> = positions1.iter().map(|&[x, _, y]| (x.into(), y.into())).collect();
32 chart.draw_series(LineSeries::new(series1, &RED)).unwrap()
33 .label("Dataset 1")
34 .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));
35
36 let series2: Vec<(f64, f64)> = positions2.iter().map(|&[x, _, y]| (x.into(), y.into())).collect();
38 chart.draw_series(LineSeries::new(series2, &BLUE)).unwrap()
39 .label("Dataset 2")
40 .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &BLUE));
41
42 chart.configure_series_labels().border_style(&BLACK).draw().unwrap();
44 Ok(())
45 }
46
47 #[test]
48 fn no_rng() -> Result<(), Error> {
49 let game_gen = SM64GameGenerator::new(include_bytes!("../../baserom.us.z64").to_vec())?;
50 let mut game = game_gen.create_game()?;
52
53 let mut i = 0;
54 while i < 2000 {
55
56 let mut button: u16 = 0;
57 let stick_x: i8 = 0;
58 let mut stick_y: i8 = 0;
59
60 if (150 < i && i < 160) || (200 < i && i < 300) {
61 button = buttons::START_BUTTON;
62 }
63
64 if i > 300 {
65 stick_y = 80;
66 }
67
68 if i % 2 == 0 {
69 button = buttons::A_BUTTON;
70 }
71
72 let pad = GamePad::new(button, stick_x, stick_y);
73 game.step_game(pad)?;
74
75
76 let state = game.get_game_state()?;
77 println!("{}\n", state.to_string());
78 i += 1;
79 }
80
81 Ok(())
82 }
83 #[test]
84 fn yes_rng() -> Result<(), Error> {
85 let game_gen = SM64GameGenerator::new(include_bytes!("../../baserom.us.z64").to_vec())?;
86 let mut game = game_gen.create_game()?;
88
89 let seed = 22;
90 game.set_rng_seed(seed)?;
94
95 let mut i = 0;
96 while i < 2000 {
97
98 let mut button: u16 = 0;
99 let stick_x: i8 = 0;
100 let stick_y: i8 = 0;
101
102 if (150 < i && i < 160) || (200 < i && i < 300) {
103 button = buttons::START_BUTTON;
104 }
105
106
107 let mut pad = GamePad::new(button, stick_x, stick_y);
108 pad = game.rng_pad(pad)?;
109 game.step_game(pad)?;
110
111
112 print!("{:#?}\n", pad);
115 i += 1;
116 }
117
118 Ok(())
119 }
120 #[test]
121 fn mem_test() -> Result<(), Box<dyn std::error::Error>> {
122 let game_gen = SM64GameGenerator::new(include_bytes!("../../baserom.us.z64").to_vec())?;
124
125 let mut game = game_gen.create_game()?;
126 let mut game2 = game_gen.create_game()?;
127
128 let mut positions_list = Vec::new();
129 let mut positions_clone_list = Vec::new();
130
131 for i in 0..3000 { let mut button = 0;
135 let mut sticky = 0;
136
137 if (150 < i && i < 160) || (200 < i && i < 300) {
138 button = buttons::START_BUTTON;
139 }
140
141 if i > 300 {
142 sticky = 80;
143 }
144
145 if i % 2 == 0 {
146 button = buttons::A_BUTTON; }
148
149 let pad = GamePad::new(button, 0, sticky);
150 if i == 1760 {
151 game.copy_to(&mut game2)?; }
153
154 if i >= 1760 {
155
156 let mut button2 = 0;
157 if button2 % 8 == 0 {
158 button2 = buttons::A_BUTTON;
159 }
160 let pad2 = GamePad::new(button2, 40, 80);
161 game2.step_game(pad2)?;
162
163 let state2 = game2.get_game_state()?;
164 positions_clone_list.push(state2.pos);
165
166 }
167
168 game.step_game(pad)?;
170
171 let state = game.get_game_state()?;
173 positions_list.push(state.pos);
174 }
175
176 visualize_positions(&positions_list, &positions_clone_list)?;
178 Ok(())
179 }
180}