Skip to content

Commit 961aa7a

Browse files
authored
add harddrop.rs (#131)
Put together to measure cycle count in the routines used by harddrop, mainly isPositionValid. Not an exhaustive test but is a starting point for further testing. Maximum cycles measured in playerControlsActiveTetrimino at the time of this commit is 21,875.
1 parent a222aa4 commit 961aa7a

File tree

2 files changed

+236
-1
lines changed

2 files changed

+236
-1
lines changed

tests/src/harddrop.rs

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
2+
use rusticnes_core::nes::NesState;
3+
4+
use crate::{ util, labels, playfield};
5+
6+
const TETRIS_READY: &str = r##"#
7+
#
8+
#
9+
#
10+
#
11+
#
12+
#
13+
#
14+
#
15+
#
16+
#
17+
#
18+
#
19+
#
20+
#
21+
#
22+
##### ####
23+
##### ####
24+
##### ####
25+
##### ####"##;
26+
27+
const TETRIS_READY_FULL: &str = r##"##### ####
28+
##### ####
29+
##### ####
30+
##### ####
31+
##### ####
32+
##### ####
33+
##### ####
34+
##### ####
35+
##### ####
36+
##### ####
37+
##### ####
38+
##### ####
39+
##### ####
40+
##### ####
41+
##### ####
42+
##### ####
43+
##### ####
44+
##### ####
45+
##### ####
46+
##### ####"##;
47+
48+
const TETRIS_FULL_AFTER: &str = r##"
49+
50+
51+
52+
##### ####
53+
##### ####
54+
##### ####
55+
##### ####
56+
##### ####
57+
##### ####
58+
##### ####
59+
##### ####
60+
##### ####
61+
##### ####
62+
##### ####
63+
##### ####
64+
##### ####
65+
##### ####
66+
##### ####
67+
##### ####"##;
68+
69+
const TEST1_AFTER: &str = r##"
70+
71+
72+
73+
#
74+
#
75+
#
76+
#
77+
#
78+
#
79+
#
80+
#
81+
#
82+
#
83+
#
84+
#
85+
#
86+
#
87+
#
88+
#"##;
89+
90+
const TEST2_AFTER: &str = r##"
91+
92+
#
93+
#
94+
#
95+
#
96+
#
97+
#
98+
#
99+
#
100+
#
101+
#
102+
#
103+
#
104+
#
105+
#
106+
#
107+
# ##
108+
##### ####
109+
##### ####"##;
110+
111+
112+
const TETRIS_READY_PC: &str = r##"
113+
114+
115+
116+
117+
118+
119+
120+
121+
122+
123+
124+
125+
126+
127+
##### ####
128+
##### ####
129+
##### ####
130+
##### ####"##;
131+
132+
133+
const BLANK_BOARD: &str = r##"
134+
135+
136+
137+
138+
139+
140+
141+
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+
152+
"##;
153+
154+
pub fn test() {
155+
let mut emu = util::emulator(None);
156+
let mut max_stage: u32;
157+
let mut max_drop: u32;
158+
let mut stage_cycles: u32;
159+
let mut drop_cycles: u32;
160+
161+
(max_stage, max_drop) = test_harddropped_piece(&mut emu, TETRIS_READY, TEST1_AFTER, 0x11);
162+
163+
(stage_cycles, drop_cycles) = test_harddropped_piece(&mut emu, TETRIS_READY, TEST2_AFTER, 0xF);
164+
max_stage = if stage_cycles > max_stage { stage_cycles } else { max_stage };
165+
max_drop = if drop_cycles > max_drop { drop_cycles } else { max_drop };
166+
167+
(stage_cycles, drop_cycles) = test_harddropped_piece(&mut emu, TETRIS_READY_PC, BLANK_BOARD, 0x11);
168+
max_stage = if stage_cycles > max_stage { stage_cycles } else { max_stage };
169+
max_drop = if drop_cycles > max_drop { drop_cycles } else { max_drop };
170+
171+
(stage_cycles, drop_cycles) = test_harddropped_piece(&mut emu, TETRIS_READY_FULL, TETRIS_FULL_AFTER, 0x11);
172+
max_stage = if stage_cycles > max_stage { stage_cycles } else { max_stage };
173+
max_drop = if drop_cycles > max_drop { drop_cycles } else { max_drop };
174+
175+
println!("Hard Drop max stage cycles: {}", max_stage);
176+
println!("Hard Drop max drop cycles: {}", max_drop);
177+
178+
}
179+
180+
fn test_harddropped_piece(emu: &mut NesState, start: &str, finish: &str, piece: u8 ) -> (u32,u32) {
181+
emu.reset();
182+
183+
for _ in 0..3 { emu.run_until_vblank(); }
184+
185+
let game_mode = labels::get("gameMode") as usize;
186+
let main_loop = labels::get("mainLoop");
187+
let level_number = labels::get("levelNumber") as usize;
188+
let practise_type = labels::get("practiseType") as usize;
189+
let mode_harddrop = labels::get("MODE_HARDDROP") as u8;
190+
let button_up = labels::get("BUTTON_UP") as u8;
191+
let newly_pressed_buttons = labels::get("newlyPressedButtons") as usize;
192+
let active_tetrimino = labels::get("playState_playerControlsActiveTetrimino");
193+
let stage_sprite = labels::get("stageSpriteForCurrentPiece");
194+
195+
emu.memory.iram_raw[practise_type] = mode_harddrop;
196+
emu.memory.iram_raw[game_mode] = 4;
197+
emu.memory.iram_raw[level_number] = 18;
198+
emu.registers.pc = main_loop;
199+
emu.memory.iram_raw[labels::get("playfieldAddr") as usize + 1] = 4;
200+
201+
playfield::clear(emu);
202+
util::run_n_vblanks(emu, 7);
203+
playfield::set_str(emu, start);
204+
205+
emu.memory.iram_raw[labels::get("playState") as usize] = 1;
206+
emu.memory.iram_raw[labels::get("currentPiece") as usize] = piece;
207+
emu.memory.iram_raw[labels::get("tetriminoX") as usize] = 0x5;
208+
emu.memory.iram_raw[labels::get("tetriminoY") as usize] = 0x0;
209+
210+
// stage ghost piece
211+
let temp_pc = emu.registers.pc;
212+
emu.registers.pc = stage_sprite;
213+
let stage_cycles = util::cycles_to_return(emu);
214+
emu.registers.pc = temp_pc;
215+
216+
util::run_n_vblanks(emu, 1);
217+
218+
emu.memory.iram_raw[labels::get("playState") as usize] = 1;
219+
emu.memory.iram_raw[labels::get("autorepeatY") as usize] = 0;
220+
emu.memory.iram_raw[labels::get("currentPiece") as usize] = piece;
221+
emu.memory.iram_raw[labels::get("tetriminoX") as usize] = 0x5;
222+
emu.memory.iram_raw[labels::get("tetriminoY") as usize] = 0x0;
223+
emu.memory.iram_raw[labels::get("vramRow") as usize] = 0x20;
224+
emu.memory.iram_raw[newly_pressed_buttons] = button_up;
225+
226+
// hard drop and count cycles
227+
emu.registers.pc = active_tetrimino;
228+
let drop_cycles = util::cycles_to_return(emu);
229+
230+
assert_eq!(finish, playfield::get_str(emu));
231+
232+
return (stage_cycles, drop_cycles);
233+
}

tests/src/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod crunch;
1212
mod drought;
1313
mod floor;
1414
mod garbage;
15+
mod harddrop;
1516
mod mapper;
1617
mod palettes;
1718
mod pushdown;
@@ -56,7 +57,7 @@ struct TestOptions {
5657
fn main() {
5758
let options = TestOptions::parse_args_default_or_exit();
5859

59-
let tests: [(&str, fn()); 16] = [
60+
let tests: [(&str, fn()); 17] = [
6061
("garbage4", garbage::test_garbage4_crash),
6162
("floor", floor::test),
6263
("tspins", tspins::test),
@@ -73,6 +74,7 @@ fn main() {
7374
("constants", constants::test),
7475
("patch", patch::test),
7576
("crunch", crunch::test),
77+
("harddrop", harddrop::test),
7678
];
7779

7880
// run tests

0 commit comments

Comments
 (0)