Fix bugs with the algorithm and add a bitplane rendering function

This commit is contained in:
Franco Colmenarez 2021-05-16 21:30:23 -05:00
parent 7e38cb0bb0
commit d06cc5d91c

View File

@ -126,15 +126,16 @@ impl Buffer {
let column_height = self.height * 8; let column_height = self.height * 8;
self.bytes[self.byte_index] = self.bytes[self.byte_index] | (data << 8 - (self.bit_index + 2)); self.bytes[self.byte_index] = self.bytes[self.byte_index] | (data << 8 - (self.bit_index + 2));
// println!("Byte {:08b}", self.bytes[self.byte_index]);
self.byte_index += 1; self.byte_index += 1;
self.row_index += 1; self.row_index += 1;
// We have reached the end of the column // We have reached the end of the column
if self.row_index >= column_height as usize { if self.row_index >= column_height as usize {
self.row_index = 0; self.row_index = 0;
self.bit_index += 2;// Next column (in bits)
self.byte_index -= column_height as usize; self.byte_index -= column_height as usize;
if self.bit_index >= 7 { self.bit_index += 2;// Next column (in bits)
if self.bit_index >= 8 {
self.bit_index = 0; self.bit_index = 0;
// Jump to the next column // Jump to the next column
self.byte_index += column_height as usize; self.byte_index += column_height as usize;
@ -282,15 +283,15 @@ impl Buffer {
1 => 7 * 7 * 8, // Address at 392 1 => 7 * 7 * 8, // Address at 392
_ => 7 * 7 * 8 * 2, // Address at 784 _ => 7 * 7 * 8 * 2, // Address at 784
}; };
let mut row_index = 0; let end_index = 8 * 7 * 7;
let row_height = self.height as usize * 8; // Height in bits let mut index = 0;
while row_index < row_height { while index < end_index {
self.bytes[(row_index + replace_index_offset) as usize] = self.bytes[index + replace_index_offset] =
self.bytes[(row_index + replace_index_offset) as usize] ^ self.bytes[index + replace_index_offset] ^
self.bytes[(row_index + buffer_index_offset) as usize]; self.bytes[index + buffer_index_offset];
row_index += 1; index += 1;
} }
} }
@ -421,7 +422,7 @@ impl Buffer {
current_row_pixel_count = 0; current_row_pixel_count = 0;
pixel_col -= 8; pixel_col -= 8;
pixel_row += 1; pixel_row += 1;
if pixel_row > pixel_height { if pixel_row >= pixel_height {
pixel_col += 8; pixel_col += 8;
pixel_row = 0; pixel_row = 0;
} }
@ -434,48 +435,28 @@ impl Buffer {
println!("Total pixels count: {}", total_pixels_count); println!("Total pixels count: {}", total_pixels_count);
} }
fn render_all_buffers(&self) { fn render_bitplanes(&self) {
println!("{}", termion::clear::All); println!("{}", termion::clear::All);
let pixel_height = 7 * 8; let pixel_height = 7 * 8;
let mut pixel_row = 0; let mut pixel_row = 0;
let mut pixel_col = 0; let mut pixel_col = 0;
let mut current_row_pixel_count = 0;
let mut total_pixels_count = 0;
for byte in &self.bytes[..] { for byte in &self.bytes[..] {
let mut shift: u8 = 8; let coords = termion::cursor::Goto(pixel_col + 1, pixel_row + 1);
let mut count = 0; let byte_string = format!("{:08b}", byte);
while count < 4 { let new_string: String = byte_string.chars().map(|x| match x {
shift -= 2; '0' => ' ',
let bit_pair = (byte >> shift) & 0b00000011; _ => '@',
count += 1; }).collect();
print!("{}{}", coords, new_string);
let coords = termion::cursor::Goto(pixel_col + 1, pixel_row + 1); pixel_row += 1;
if pixel_row >= pixel_height {
match bit_pair { pixel_row = 0;
0 => print!("{goto}{color} ", goto = coords, color = termion::color::Bg(termion::color::White)), pixel_col += 8;
_ => print!("{goto}{color} ", goto = coords, color = termion::color::Bg(termion::color::Black)),
}
total_pixels_count += 1;
pixel_col += 1;
current_row_pixel_count += 1;
if current_row_pixel_count > 7 {
current_row_pixel_count = 0;
pixel_col -= 8;
pixel_row += 1;
if pixel_row > pixel_height {
pixel_col += 8;
pixel_row = 0;
}
}
} }
} }
println!("");
println!("{reset}", reset = termion::style::Reset);
println!("Total pixels count: {}", total_pixels_count);
} }
} }
@ -486,8 +467,8 @@ fn main() {
let filename = match &args.get(1) { let filename = match &args.get(1) {
Some(filename) => filename.clone(), Some(filename) => filename.clone(),
None => panic!("No filename specified!"), // None => panic!("No filename specified!"),
// None => "surprise.pkz", None => "surprise.pkz",
}; };
println!("Filename: {}", &filename); println!("Filename: {}", &filename);
@ -539,7 +520,7 @@ fn main() {
println!("Starting to decompress the first buffer!"); println!("Starting to decompress the first buffer!");
buffer.decompress_to_bitplane(&mut sprite_bytes, initial_packet, primary_buffer == 0, true); buffer.decompress_to_bitplane(&mut sprite_bytes, initial_packet, primary_buffer == 0, true);
println!("{:02X?}", buffer.bytes); // println!("{:02X?}", buffer.bytes);
let encoding_mode: EncodingMode = { let encoding_mode: EncodingMode = {
if sprite_bytes.current_bit() == 0 { if sprite_bytes.current_bit() == 0 {
@ -565,7 +546,7 @@ fn main() {
println!("Starting to decompress the second buffer!"); println!("Starting to decompress the second buffer!");
let initial_packet: u8 = sprite_bytes.read_bits(1, false); // Read next 1 bit let initial_packet: u8 = sprite_bytes.read_bits(1, false); // Read next 1 bit
buffer.decompress_to_bitplane(&mut sprite_bytes, initial_packet, primary_buffer == 1, false); buffer.decompress_to_bitplane(&mut sprite_bytes, initial_packet, primary_buffer == 1, false);
println!("{:02X?}", buffer.bytes); // println!("{:02X?}", buffer.bytes);
// In mode 1 and 3, we have to delta-decode the buffer C // In mode 1 and 3, we have to delta-decode the buffer C
// In any mode, we have to delta-decode the buffer B // In any mode, we have to delta-decode the buffer B
@ -578,28 +559,29 @@ fn main() {
}, },
EncodingMode::Mode2 => { EncodingMode::Mode2 => {
buffer.delta_decode(1); buffer.delta_decode(1);
buffer.xor_buffers(1, 2); buffer.xor_buffers(2, 1);
}, },
EncodingMode::Mode3 => { EncodingMode::Mode3 => {
buffer.delta_decode(2); buffer.delta_decode(2);
buffer.xor_buffers(1, 2); buffer.delta_decode(1);
buffer.xor_buffers(2, 1);
}, },
} }
println!("Encoding result:"); println!("Encoding result:");
println!("{:02X?}", buffer.bytes); // println!("{:02X?}", buffer.bytes);
// Now we need to copy the content from buffer B to A and from C to B, // Now we need to copy the content from buffer B to A and from C to B,
// but in the right order for the Gameboy to draw // but in the right order for the Gameboy to draw
buffer.copy_bitplane(1, 0); buffer.copy_bitplane(1, 0);
buffer.copy_bitplane(2, 1); buffer.copy_bitplane(2, 1);
println!("Bitplane copy result:"); println!("Bitplane copy result:");
println!("{:02X?}", buffer.bytes); // println!("{:02X?}", buffer.bytes);
// Almost there! // Almost there!
// Now we need to zipper the buffer A and B into buffer C and B going backwards // Now we need to zipper the buffer A and B into buffer C and B going backwards
buffer.zip_buffers(); buffer.zip_buffers();
println!("Resulting zip:"); println!("Resulting zip:");
println!("{:02X?}", buffer.bytes); // println!("{:02X?}", buffer.bytes);
// And we can finally start rendering our sprite!!! // And we can finally start rendering our sprite!!!
buffer.render(); buffer.render();