|
| 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 | +} |
0 commit comments