mirror of
https://github.com/danbulant/chip8badapple
synced 2026-07-05 19:20:35 +00:00
correct sprite splitting
This commit is contained in:
parent
f84466c03a
commit
ea272b611f
1 changed files with 62 additions and 35 deletions
97
src/main.rs
97
src/main.rs
|
|
@ -31,10 +31,10 @@ fn main() -> Result<(), ffmpeg_next::Error> {
|
||||||
decoder.width(),
|
decoder.width(),
|
||||||
decoder.height(),
|
decoder.height(),
|
||||||
// output
|
// output
|
||||||
Pixel::MonoBlack,
|
Pixel::GRAY8,
|
||||||
WIDTH as u32,
|
WIDTH as u32,
|
||||||
HEIGHT as u32,
|
HEIGHT as u32,
|
||||||
Flags::BILINEAR
|
Flags::BICUBIC
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut frame_index = 0;
|
let mut frame_index = 0;
|
||||||
|
|
@ -43,7 +43,7 @@ fn main() -> Result<(), ffmpeg_next::Error> {
|
||||||
// V0=x, V1=y, V10=VA=frame count, V11=VB=delay timer
|
// V0=x, V1=y, V10=VA=frame count, V11=VB=delay timer
|
||||||
// it uses sprite bank to draw sprites on the screen
|
// it uses sprite bank to draw sprites on the screen
|
||||||
// because of frame counting, maximum length is roughly 36.4 minutes (for 30fps)
|
// because of frame counting, maximum length is roughly 36.4 minutes (for 30fps)
|
||||||
let base_rom = [
|
let base_rom: [u8; 50] = [
|
||||||
0xA3,0x00, // 0x200 I = 0x300
|
0xA3,0x00, // 0x200 I = 0x300
|
||||||
0x6C,0x01, // 0x202 VC = 1
|
0x6C,0x01, // 0x202 VC = 1
|
||||||
|
|
||||||
|
|
@ -51,32 +51,37 @@ fn main() -> Result<(), ffmpeg_next::Error> {
|
||||||
0x00,0xE0, // 0x204 clear screen,
|
0x00,0xE0, // 0x204 clear screen,
|
||||||
0x61,0x00, // 0x206 V1 = 0
|
0x61,0x00, // 0x206 V1 = 0
|
||||||
0x60,0x00, // 0x208 V0 = 0
|
0x60,0x00, // 0x208 V0 = 0
|
||||||
0xD0,0x1F, // 0x20A draw sprite at V0, V1 with height 15
|
0x31, 30, // 0x20A if V1 == 30 skip
|
||||||
0x70,0x08, // 0x20C V0 += 8
|
0xD0,0x1F, // 0x20C draw sprite at V0, V1 with height 15
|
||||||
0x62, 120, // 0x20E V2 = 120
|
0x41, 30, // 0x20E if V1 != 30 skip
|
||||||
0xF2,0x1E, // 0x210 I += V2
|
0xD0,0x12, // 0x210 draw sprite at V0, V1 with height 2
|
||||||
|
0x70,0x08, // 0x212 V0 += 8
|
||||||
|
0x62, 120, // 0x214 V2 = 120
|
||||||
|
0xF2,0x1E, // 0x216 I += V2
|
||||||
|
|
||||||
0x30, 32, // 0x212 if V0 == 32 skip
|
0x30,WIDTH, // 0x218 if V0 == WIDTH (64) skip
|
||||||
0x12,0x0A, // 0x214 goto 0x20A
|
0x12,0x0A, // 0x21A goto 0x20A
|
||||||
0x71, 15, // 0x216 V1 += 15
|
0x71, 15, // 0x21C V1 += 15
|
||||||
0x31, 45, // 0x218 if V1 == 45 skip
|
0x31, 45, // 0x21E if V1 == 45 skip
|
||||||
0x12,0x08, // 0x21A goto 0x208
|
0x12,0x08, // 0x220 goto 0x208
|
||||||
|
|
||||||
// wait for next frame. Delay timer ticks every 1/60th of a second, video is 30fps, hence 2 ticks
|
// wait for next frame. Delay timer ticks every 1/60th of a second, video is 30fps, hence 2 ticks
|
||||||
0x6B,0x02, // 0x21C VB = 2
|
0x6B,0x02, // 0x222 VB = 2
|
||||||
0xFB,0x15, // 0x21E delay timer = VB
|
0xFB,0x15, // 0x224 delay timer = VB
|
||||||
0xFB,0x07, // 0x220 VB = delay timer
|
0xFB,0x07, // 0x226 VB = delay timer
|
||||||
|
|
||||||
0x4B,0x00, // 0x222 if VB != 0 skip
|
0x4B,0x00, // 0x228 if VB != 0 skip
|
||||||
0x12,0x22, // 0x224 goto 0x222
|
0x12,0x22, // 0x22A goto 0x222 (repeat wait)
|
||||||
|
|
||||||
0x12,0x04, // 0x226 goto 0x204
|
0x12,0x04, // 0x22C goto 0x204
|
||||||
// unreachable, for future use
|
// unreachable, for future use
|
||||||
0x12,0x28, // 0x228 goto 0x228 (self jump, our emulator exits)
|
0x12,0x2E, // 0x22E goto 0x22E (self jump, our emulator exits)
|
||||||
0x00,0x00 // crash if we get here
|
0x00,0x00 // crash if we get here
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// dbg!(&base_rom);
|
||||||
output_file.write_all(&base_rom).unwrap();
|
output_file.write_all(&base_rom).unwrap();
|
||||||
output_file.seek(std::io::SeekFrom::Start(0x300)).unwrap();
|
output_file.seek(std::io::SeekFrom::Start(0x100)).unwrap();
|
||||||
|
|
||||||
let mut receive_and_process_decoded_frames =
|
let mut receive_and_process_decoded_frames =
|
||||||
|decoder: &mut ffmpeg_next::decoder::Video| -> Result<(), ffmpeg_next::Error> {
|
|decoder: &mut ffmpeg_next::decoder::Video| -> Result<(), ffmpeg_next::Error> {
|
||||||
|
|
@ -86,31 +91,53 @@ fn main() -> Result<(), ffmpeg_next::Error> {
|
||||||
scaler.run(&decoded, &mut bw_frame)?;
|
scaler.run(&decoded, &mut bw_frame)?;
|
||||||
let data = bw_frame.data(0);
|
let data = bw_frame.data(0);
|
||||||
// dbg!(data);
|
// dbg!(data);
|
||||||
let mut sprite_bank: [[u8; 8]; 3] = [
|
let mut sprite_bank: [[[u8; 15]; 8]; 3] = [
|
||||||
[
|
[
|
||||||
0; 8 // there are 8 sprites in 64 pixel wide screen
|
[
|
||||||
|
0; 15 // 15 pixel tall, 8 pixel wide (u8) sprite
|
||||||
|
]; 8 // there are 8 sprites in 64 pixel wide screen
|
||||||
]; 3 // 3 parts 15 pixels each to fill 32 pixel tall screen
|
]; 3 // 3 parts 15 pixels each to fill 32 pixel tall screen
|
||||||
];
|
];
|
||||||
|
|
||||||
for i in 0..8 {
|
for horizontal_part in 0..8 {
|
||||||
for j in 0..3 {
|
for vertical_part in 0..3 {
|
||||||
sprite_bank[j][i] = data[i * 3 + j];
|
let rows = if vertical_part == 2 { 2 } else { 15 };
|
||||||
|
for row in 0..rows {
|
||||||
|
// data is 64x32x8bit, we need to split it into 8x15x8bit chunks
|
||||||
|
for col in 0..8 {
|
||||||
|
let x = horizontal_part * 8 + col;
|
||||||
|
let y = vertical_part * 15 + row;
|
||||||
|
let pixel = data[y as usize * WIDTH as usize + x as usize];
|
||||||
|
// dbg!(pixel);
|
||||||
|
if pixel > 30 {
|
||||||
|
sprite_bank[vertical_part][horizontal_part][row] |= 1 << (7 - col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = File::create(format!("frames/f{}.pbm", frame_index)).unwrap();
|
// let mut file = File::create(format!("frames/f{}.pbm", frame_index)).unwrap();
|
||||||
file.write_all(format!("P4\n{} {}\n", bw_frame.width(), bw_frame.height()).as_bytes()).unwrap();
|
// file.write_all(format!("P5\n{} {}\n255\n", WIDTH, HEIGHT).as_bytes()).unwrap();
|
||||||
file.write_all(data).unwrap();
|
// file.write_all(data).unwrap();
|
||||||
|
|
||||||
|
for part in 0..3 {
|
||||||
|
for line in 0..15 {
|
||||||
|
for sprite in 0..8 {
|
||||||
|
print!("{:08b} ", sprite_bank[part][sprite][line]);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!("frame {}", frame_index);
|
||||||
|
println!();
|
||||||
|
|
||||||
for part in 0..3 {
|
for part in 0..3 {
|
||||||
for sprite in 0..8 {
|
for sprite in 0..8 {
|
||||||
let mut sprite_byte = 0;
|
output_file.write_all(&sprite_bank[part][sprite]).unwrap();
|
||||||
for pixel in 0..8 {
|
|
||||||
if sprite_bank[part][sprite] & 1 << (7 - pixel) != 0 {
|
|
||||||
sprite_byte |= 1 << (7 - pixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output_file.write_all(&[sprite_byte]).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue