From 7c5ce97abe4e5f7c6dfaf6528ccc77f386fcdea2 Mon Sep 17 00:00:00 2001 From: Craig Thomas Date: Tue, 9 Jul 2024 15:28:45 -0400 Subject: [PATCH 1/2] Unit tests for drawing commands. --- chip8/cpu.py | 12 ++-- test/test_chip8cpu.py | 127 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 5 deletions(-) diff --git a/chip8/cpu.py b/chip8/cpu.py index afedd9d..4e1277c 100644 --- a/chip8/cpu.py +++ b/chip8/cpu.py @@ -874,13 +874,13 @@ def draw_sprite(self): self.last_op = f"DRAWEX" else: if self.bitplane == 3: - self.draw_normal(x_pos, y_pos, num_bytes, 1) - self.draw_normal(x_pos, y_pos, num_bytes, 2) + self.draw_normal(x_pos, y_pos, num_bytes, 1, index=self.index) + self.draw_normal(x_pos, y_pos, num_bytes, 2, index=self.index + num_bytes) else: self.draw_normal(x_pos, y_pos, num_bytes, self.bitplane) self.last_op = f"DRAW V{x_source:01X}, V{y_source:01X}" - def draw_normal(self, x_pos, y_pos, num_bytes, bitplane): + def draw_normal(self, x_pos, y_pos, num_bytes, bitplane, index=None): """ Draws a sprite on the screen while in NORMAL mode. @@ -888,9 +888,13 @@ def draw_normal(self, x_pos, y_pos, num_bytes, bitplane): :param y_pos: the Y position of the sprite :param num_bytes: the number of bytes to draw :param bitplane: the bitplane to draw to + :param index: the memory index in memory where byte the pattern is stored """ + if not index: + index = self.index + for y_index in range(num_bytes): - color_byte = self.memory[self.index + y_index] + color_byte = self.memory[index + y_index] y_coord = y_pos + y_index if not self.clip_quirks or (self.clip_quirks and y_coord < self.screen.get_height()): y_coord = y_coord % self.screen.get_height() diff --git a/test/test_chip8cpu.py b/test/test_chip8cpu.py index aa00c4f..1f02af4 100644 --- a/test/test_chip8cpu.py +++ b/test/test_chip8cpu.py @@ -255,6 +255,16 @@ def test_logical_or(self): self.cpu.v[source], source_val) + def test_logical_or_logic_quirks_clears_flag(self): + self.cpu.v[1] = 0 + self.cpu.v[2] = 1 + self.cpu.v[0xF] = 1 + self.cpu.operand = 0x8121 + self.cpu.logic_quirks = True + self.cpu.logical_or() + self.assertEqual(1, self.cpu.v[1]) + self.assertEqual(0, self.cpu.v[0xF]) + def test_logical_and(self): for source in range(0x10): for target in range(0x10): @@ -279,6 +289,16 @@ def test_logical_and(self): self.cpu.v[source], source_val) + def test_logical_and_logic_quirks_clears_flag(self): + self.cpu.v[1] = 0 + self.cpu.v[2] = 1 + self.cpu.v[0xF] = 1 + self.cpu.operand = 0x8122 + self.cpu.logic_quirks = True + self.cpu.logical_and() + self.assertEqual(0, self.cpu.v[1]) + self.assertEqual(0, self.cpu.v[0xF]) + def test_exclusive_or(self): for source in range(0x10): for target in range(0x10): @@ -294,6 +314,16 @@ def test_exclusive_or(self): self.cpu.v[source], source_val ^ target_val) + def test_exclusive_or_logic_quirks_clears_flag(self): + self.cpu.v[1] = 1 + self.cpu.v[2] = 1 + self.cpu.v[0xF] = 1 + self.cpu.operand = 0x8123 + self.cpu.logic_quirks = True + self.cpu.exclusive_or() + self.assertEqual(0, self.cpu.v[1]) + self.assertEqual(0, self.cpu.v[0xF]) + def test_add_to_reg(self): for source in range(0xF): for target in range(0xF): @@ -814,7 +844,7 @@ def test_misc_routines_raises_exception_on_unknown_op_codes(self): def test_save_skip_routines_raises_exception_on_unknown_op_codes(self): self.cpu.operand = 0x50FF with self.assertRaises(UnknownOpCodeException) as context: - self.cpu.misc_routines() + self.cpu.save_skip_routines() self.assertEqual("Unknown op-code: 50FF", str(context.exception)) def test_scroll_down_called(self): @@ -857,6 +887,101 @@ def test_draw_extended_called(self): self.cpu.draw_sprite() self.assertTrue(self.cpu_spy.draw_extended.assert_called) + def test_draw_sprite_normal_bitplane_1_integration_correct(self): + self.screen = Chip8Screen(2) + self.screen.init_display() + self.cpu = Chip8CPU(self.screen) + + self.cpu.memory[0x0200] = 0xD0 + self.cpu.memory[0x0201] = 0x01 + self.cpu.memory[0x5000] = 0xAA + self.cpu.index = 0x5000 + self.cpu.bitplane = 1 + self.cpu.execute_instruction() + self.assertTrue(self.screen.get_pixel(0, 0, 1)) + self.assertFalse(self.screen.get_pixel(1, 0, 1)) + self.assertTrue(self.screen.get_pixel(2, 0, 1)) + self.assertFalse(self.screen.get_pixel(3, 0, 1)) + self.assertTrue(self.screen.get_pixel(4, 0, 1)) + self.assertFalse(self.screen.get_pixel(5, 0, 1)) + self.assertTrue(self.screen.get_pixel(6, 0, 1)) + self.assertFalse(self.screen.get_pixel(7, 0, 1)) + + # Second bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 2)) + self.assertFalse(self.screen.get_pixel(1, 0, 2)) + self.assertFalse(self.screen.get_pixel(2, 0, 2)) + self.assertFalse(self.screen.get_pixel(3, 0, 2)) + self.assertFalse(self.screen.get_pixel(4, 0, 2)) + self.assertFalse(self.screen.get_pixel(5, 0, 2)) + self.assertFalse(self.screen.get_pixel(6, 0, 2)) + self.assertFalse(self.screen.get_pixel(7, 0, 2)) + + def test_draw_sprite_normal_bitplane_2_integration_correct(self): + self.screen = Chip8Screen(2) + self.screen.init_display() + self.cpu = Chip8CPU(self.screen) + + self.cpu.memory[0x0200] = 0xD0 + self.cpu.memory[0x0201] = 0x01 + self.cpu.memory[0x5000] = 0x55 + self.cpu.index = 0x5000 + self.cpu.bitplane = 2 + self.cpu.execute_instruction() + + # First bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 1)) + self.assertFalse(self.screen.get_pixel(1, 0, 1)) + self.assertFalse(self.screen.get_pixel(2, 0, 1)) + self.assertFalse(self.screen.get_pixel(3, 0, 1)) + self.assertFalse(self.screen.get_pixel(4, 0, 1)) + self.assertFalse(self.screen.get_pixel(5, 0, 1)) + self.assertFalse(self.screen.get_pixel(6, 0, 1)) + self.assertFalse(self.screen.get_pixel(7, 0, 1)) + + # Second bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 2)) + self.assertTrue(self.screen.get_pixel(1, 0, 2)) + self.assertFalse(self.screen.get_pixel(2, 0, 2)) + self.assertTrue(self.screen.get_pixel(3, 0, 2)) + self.assertFalse(self.screen.get_pixel(4, 0, 2)) + self.assertTrue(self.screen.get_pixel(5, 0, 2)) + self.assertFalse(self.screen.get_pixel(6, 0, 2)) + self.assertTrue(self.screen.get_pixel(7, 0, 2)) + + def test_draw_sprite_normal_bitplane_3_integration_correct(self): + self.screen = Chip8Screen(2) + self.screen.init_display() + self.cpu = Chip8CPU(self.screen) + + self.cpu.memory[0x0200] = 0xD0 + self.cpu.memory[0x0201] = 0x01 + self.cpu.memory[0x5000] = 0xAA + self.cpu.memory[0x5001] = 0x55 + self.cpu.bitplane = 3 + self.cpu.index = 0x5000 + self.cpu.execute_instruction() + + # First bitplane pattern + self.assertTrue(self.screen.get_pixel(0, 0, 1)) + self.assertFalse(self.screen.get_pixel(1, 0, 1)) + self.assertTrue(self.screen.get_pixel(2, 0, 1)) + self.assertFalse(self.screen.get_pixel(3, 0, 1)) + self.assertTrue(self.screen.get_pixel(4, 0, 1)) + self.assertFalse(self.screen.get_pixel(5, 0, 1)) + self.assertTrue(self.screen.get_pixel(6, 0, 1)) + self.assertFalse(self.screen.get_pixel(7, 0, 1)) + + # Second bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 2)) + self.assertTrue(self.screen.get_pixel(1, 0, 2)) + self.assertFalse(self.screen.get_pixel(2, 0, 2)) + self.assertTrue(self.screen.get_pixel(3, 0, 2)) + self.assertFalse(self.screen.get_pixel(4, 0, 2)) + self.assertTrue(self.screen.get_pixel(5, 0, 2)) + self.assertFalse(self.screen.get_pixel(6, 0, 2)) + self.assertTrue(self.screen.get_pixel(7, 0, 2)) + def test_draw_sprite_draws_correct_sprite(self): screen = Chip8Screen(2) screen.init_display() From 904cea4c6d6ffa5b99842785729422520c038a16 Mon Sep 17 00:00:00 2001 From: Craig Thomas Date: Tue, 9 Jul 2024 20:25:08 -0400 Subject: [PATCH 2/2] Fix sprite drawing in extended mode. --- chip8/cpu.py | 12 ++- test/test_chip8cpu.py | 238 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+), 4 deletions(-) diff --git a/chip8/cpu.py b/chip8/cpu.py index 4e1277c..de18b58 100644 --- a/chip8/cpu.py +++ b/chip8/cpu.py @@ -867,8 +867,8 @@ def draw_sprite(self): if num_bytes == 0: if self.bitplane == 3: - self.draw_extended(x_pos, y_pos, 1) - self.draw_extended(x_pos, y_pos, 2) + self.draw_extended(x_pos, y_pos, 1, index=self.index) + self.draw_extended(x_pos, y_pos, 2, index=self.index + 32) else: self.draw_extended(x_pos, y_pos, self.bitplane) self.last_op = f"DRAWEX" @@ -910,7 +910,7 @@ def draw_normal(self, x_pos, y_pos, num_bytes, bitplane, index=None): mask = mask >> 1 self.screen.update() - def draw_extended(self, x_pos, y_pos, bitplane): + def draw_extended(self, x_pos, y_pos, bitplane, index=None): """ Draws a sprite on the screen while in EXTENDED mode. Sprites in this mode are assumed to be 16x16 pixels. This means that two bytes will @@ -920,10 +920,14 @@ def draw_extended(self, x_pos, y_pos, bitplane): :param x_pos: the X position of the sprite :param y_pos: the Y position of the sprite :param bitplane: the bitplane to draw to + :param index: the memory index in memory where byte the pattern is stored """ + if not index: + index = self.index + for y_index in range(16): for x_byte in range(2): - color_byte = self.memory[self.index + (y_index * 2) + x_byte] + color_byte = self.memory[index + (y_index * 2) + x_byte] y_coord = y_pos + y_index if y_coord < self.screen.get_height(): y_coord = y_coord % self.screen.get_height() diff --git a/test/test_chip8cpu.py b/test/test_chip8cpu.py index 1f02af4..bbc8bde 100644 --- a/test/test_chip8cpu.py +++ b/test/test_chip8cpu.py @@ -917,6 +917,68 @@ def test_draw_sprite_normal_bitplane_1_integration_correct(self): self.assertFalse(self.screen.get_pixel(6, 0, 2)) self.assertFalse(self.screen.get_pixel(7, 0, 2)) + def test_draw_sprite_extended_bitplane_1_integration_correct(self): + self.screen = Chip8Screen(2) + self.screen.init_display() + self.cpu = Chip8CPU(self.screen) + + self.cpu.memory[0x0200] = 0xD0 + self.cpu.memory[0x0201] = 0x00 + self.cpu.memory[0x5000] = 0xAA + self.cpu.memory[0x5001] = 0x55 + self.cpu.memory[0x5002] = 0xAA + self.cpu.memory[0x5003] = 0x55 + self.cpu.memory[0x5004] = 0xAA + self.cpu.memory[0x5005] = 0x55 + self.cpu.memory[0x5006] = 0xAA + self.cpu.memory[0x5007] = 0x55 + self.cpu.memory[0x5008] = 0xAA + self.cpu.memory[0x5009] = 0x55 + self.cpu.memory[0x500A] = 0xAA + self.cpu.memory[0x500B] = 0x55 + self.cpu.memory[0x500C] = 0xAA + self.cpu.memory[0x500D] = 0x55 + self.cpu.memory[0x500E] = 0xAA + self.cpu.memory[0x500F] = 0x55 + + self.cpu.index = 0x5000 + self.cpu.bitplane = 1 + self.cpu.execute_instruction() + self.assertTrue(self.screen.get_pixel(0, 0, 1)) + self.assertFalse(self.screen.get_pixel(1, 0, 1)) + self.assertTrue(self.screen.get_pixel(2, 0, 1)) + self.assertFalse(self.screen.get_pixel(3, 0, 1)) + self.assertTrue(self.screen.get_pixel(4, 0, 1)) + self.assertFalse(self.screen.get_pixel(5, 0, 1)) + self.assertTrue(self.screen.get_pixel(6, 0, 1)) + self.assertFalse(self.screen.get_pixel(7, 0, 1)) + self.assertFalse(self.screen.get_pixel(8, 0, 1)) + self.assertTrue(self.screen.get_pixel(9, 0, 1)) + self.assertFalse(self.screen.get_pixel(10, 0, 1)) + self.assertTrue(self.screen.get_pixel(11, 0, 1)) + self.assertFalse(self.screen.get_pixel(12, 0, 1)) + self.assertTrue(self.screen.get_pixel(13, 0, 1)) + self.assertFalse(self.screen.get_pixel(14, 0, 1)) + self.assertTrue(self.screen.get_pixel(15, 0, 1)) + + # Second bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 2)) + self.assertFalse(self.screen.get_pixel(1, 0, 2)) + self.assertFalse(self.screen.get_pixel(2, 0, 2)) + self.assertFalse(self.screen.get_pixel(3, 0, 2)) + self.assertFalse(self.screen.get_pixel(4, 0, 2)) + self.assertFalse(self.screen.get_pixel(5, 0, 2)) + self.assertFalse(self.screen.get_pixel(6, 0, 2)) + self.assertFalse(self.screen.get_pixel(7, 0, 2)) + self.assertFalse(self.screen.get_pixel(8, 0, 2)) + self.assertFalse(self.screen.get_pixel(9, 0, 2)) + self.assertFalse(self.screen.get_pixel(10, 0, 2)) + self.assertFalse(self.screen.get_pixel(11, 0, 2)) + self.assertFalse(self.screen.get_pixel(12, 0, 2)) + self.assertFalse(self.screen.get_pixel(13, 0, 2)) + self.assertFalse(self.screen.get_pixel(14, 0, 2)) + self.assertFalse(self.screen.get_pixel(15, 0, 2)) + def test_draw_sprite_normal_bitplane_2_integration_correct(self): self.screen = Chip8Screen(2) self.screen.init_display() @@ -949,6 +1011,68 @@ def test_draw_sprite_normal_bitplane_2_integration_correct(self): self.assertFalse(self.screen.get_pixel(6, 0, 2)) self.assertTrue(self.screen.get_pixel(7, 0, 2)) + def test_draw_sprite_extended_bitplane_2_integration_correct(self): + self.screen = Chip8Screen(2) + self.screen.init_display() + self.cpu = Chip8CPU(self.screen) + + self.cpu.memory[0x0200] = 0xD0 + self.cpu.memory[0x0201] = 0x00 + self.cpu.memory[0x5000] = 0xAA + self.cpu.memory[0x5001] = 0x55 + self.cpu.memory[0x5002] = 0xAA + self.cpu.memory[0x5003] = 0x55 + self.cpu.memory[0x5004] = 0xAA + self.cpu.memory[0x5005] = 0x55 + self.cpu.memory[0x5006] = 0xAA + self.cpu.memory[0x5007] = 0x55 + self.cpu.memory[0x5008] = 0xAA + self.cpu.memory[0x5009] = 0x55 + self.cpu.memory[0x500A] = 0xAA + self.cpu.memory[0x500B] = 0x55 + self.cpu.memory[0x500C] = 0xAA + self.cpu.memory[0x500D] = 0x55 + self.cpu.memory[0x500E] = 0xAA + self.cpu.memory[0x500F] = 0x55 + + self.cpu.index = 0x5000 + self.cpu.bitplane = 2 + self.cpu.execute_instruction() + self.assertTrue(self.screen.get_pixel(0, 0, 2)) + self.assertFalse(self.screen.get_pixel(1, 0, 2)) + self.assertTrue(self.screen.get_pixel(2, 0, 2)) + self.assertFalse(self.screen.get_pixel(3, 0, 2)) + self.assertTrue(self.screen.get_pixel(4, 0, 2)) + self.assertFalse(self.screen.get_pixel(5, 0, 2)) + self.assertTrue(self.screen.get_pixel(6, 0, 2)) + self.assertFalse(self.screen.get_pixel(7, 0, 2)) + self.assertFalse(self.screen.get_pixel(8, 0, 2)) + self.assertTrue(self.screen.get_pixel(9, 0, 2)) + self.assertFalse(self.screen.get_pixel(10, 0, 2)) + self.assertTrue(self.screen.get_pixel(11, 0, 2)) + self.assertFalse(self.screen.get_pixel(12, 0, 2)) + self.assertTrue(self.screen.get_pixel(13, 0, 2)) + self.assertFalse(self.screen.get_pixel(14, 0, 2)) + self.assertTrue(self.screen.get_pixel(15, 0, 2)) + + # Second bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 1)) + self.assertFalse(self.screen.get_pixel(1, 0, 1)) + self.assertFalse(self.screen.get_pixel(2, 0, 1)) + self.assertFalse(self.screen.get_pixel(3, 0, 1)) + self.assertFalse(self.screen.get_pixel(4, 0, 1)) + self.assertFalse(self.screen.get_pixel(5, 0, 1)) + self.assertFalse(self.screen.get_pixel(6, 0, 1)) + self.assertFalse(self.screen.get_pixel(7, 0, 1)) + self.assertFalse(self.screen.get_pixel(8, 0, 1)) + self.assertFalse(self.screen.get_pixel(9, 0, 1)) + self.assertFalse(self.screen.get_pixel(10, 0, 1)) + self.assertFalse(self.screen.get_pixel(11, 0, 1)) + self.assertFalse(self.screen.get_pixel(12, 0, 1)) + self.assertFalse(self.screen.get_pixel(13, 0, 1)) + self.assertFalse(self.screen.get_pixel(14, 0, 1)) + self.assertFalse(self.screen.get_pixel(15, 0, 1)) + def test_draw_sprite_normal_bitplane_3_integration_correct(self): self.screen = Chip8Screen(2) self.screen.init_display() @@ -982,6 +1106,120 @@ def test_draw_sprite_normal_bitplane_3_integration_correct(self): self.assertFalse(self.screen.get_pixel(6, 0, 2)) self.assertTrue(self.screen.get_pixel(7, 0, 2)) + def test_draw_sprite_extended_bitplane_3_integration_correct(self): + self.screen = Chip8Screen(2) + self.screen.init_display() + self.cpu = Chip8CPU(self.screen) + + self.cpu.memory[0x0200] = 0xD0 + self.cpu.memory[0x0201] = 0x00 + + self.cpu.memory[0x5000] = 0xAA + self.cpu.memory[0x5001] = 0x55 + self.cpu.memory[0x5002] = 0xAA + self.cpu.memory[0x5003] = 0x55 + self.cpu.memory[0x5004] = 0xAA + self.cpu.memory[0x5005] = 0x55 + self.cpu.memory[0x5006] = 0xAA + self.cpu.memory[0x5007] = 0x55 + self.cpu.memory[0x5008] = 0xAA + self.cpu.memory[0x5009] = 0x55 + self.cpu.memory[0x500A] = 0xAA + self.cpu.memory[0x500B] = 0x55 + self.cpu.memory[0x500C] = 0xAA + self.cpu.memory[0x500D] = 0x55 + self.cpu.memory[0x500E] = 0xAA + self.cpu.memory[0x500F] = 0x55 + + self.cpu.memory[0x5010] = 0x55 + self.cpu.memory[0x5011] = 0xAA + self.cpu.memory[0x5012] = 0x55 + self.cpu.memory[0x5013] = 0xAA + self.cpu.memory[0x5014] = 0x55 + self.cpu.memory[0x5015] = 0xAA + self.cpu.memory[0x5016] = 0x55 + self.cpu.memory[0x5017] = 0xAA + self.cpu.memory[0x5018] = 0x55 + self.cpu.memory[0x5019] = 0xAA + self.cpu.memory[0x501A] = 0x55 + self.cpu.memory[0x501B] = 0xAA + self.cpu.memory[0x501C] = 0x55 + self.cpu.memory[0x501D] = 0xAA + self.cpu.memory[0x501E] = 0x55 + self.cpu.memory[0x501F] = 0xAA + + self.cpu.memory[0x5020] = 0x55 + self.cpu.memory[0x5021] = 0xAA + self.cpu.memory[0x5022] = 0x55 + self.cpu.memory[0x5023] = 0xAA + self.cpu.memory[0x5024] = 0x55 + self.cpu.memory[0x5025] = 0xAA + self.cpu.memory[0x5026] = 0x55 + self.cpu.memory[0x5027] = 0xAA + self.cpu.memory[0x5028] = 0x55 + self.cpu.memory[0x5029] = 0xAA + self.cpu.memory[0x502A] = 0x55 + self.cpu.memory[0x502B] = 0xAA + self.cpu.memory[0x502C] = 0x55 + self.cpu.memory[0x502D] = 0xAA + self.cpu.memory[0x502E] = 0x55 + self.cpu.memory[0x502F] = 0xAA + + self.cpu.memory[0x5030] = 0xAA + self.cpu.memory[0x5031] = 0x55 + self.cpu.memory[0x5032] = 0xAA + self.cpu.memory[0x5033] = 0x55 + self.cpu.memory[0x5034] = 0xAA + self.cpu.memory[0x5035] = 0x55 + self.cpu.memory[0x5036] = 0xAA + self.cpu.memory[0x5037] = 0x55 + self.cpu.memory[0x5038] = 0xAA + self.cpu.memory[0x5039] = 0x55 + self.cpu.memory[0x503A] = 0xAA + self.cpu.memory[0x503B] = 0x55 + self.cpu.memory[0x503C] = 0xAA + self.cpu.memory[0x503D] = 0x55 + self.cpu.memory[0x503E] = 0xAA + self.cpu.memory[0x503F] = 0x55 + + self.cpu.index = 0x5000 + self.cpu.bitplane = 3 + self.cpu.execute_instruction() + self.assertTrue(self.screen.get_pixel(0, 0, 1)) + self.assertFalse(self.screen.get_pixel(1, 0, 1)) + self.assertTrue(self.screen.get_pixel(2, 0, 1)) + self.assertFalse(self.screen.get_pixel(3, 0, 1)) + self.assertTrue(self.screen.get_pixel(4, 0, 1)) + self.assertFalse(self.screen.get_pixel(5, 0, 1)) + self.assertTrue(self.screen.get_pixel(6, 0, 1)) + self.assertFalse(self.screen.get_pixel(7, 0, 1)) + self.assertFalse(self.screen.get_pixel(8, 0, 1)) + self.assertTrue(self.screen.get_pixel(9, 0, 1)) + self.assertFalse(self.screen.get_pixel(10, 0, 1)) + self.assertTrue(self.screen.get_pixel(11, 0, 1)) + self.assertFalse(self.screen.get_pixel(12, 0, 1)) + self.assertTrue(self.screen.get_pixel(13, 0, 1)) + self.assertFalse(self.screen.get_pixel(14, 0, 1)) + self.assertTrue(self.screen.get_pixel(15, 0, 1)) + + # Second bitplane pattern + self.assertFalse(self.screen.get_pixel(0, 0, 2)) + self.assertTrue(self.screen.get_pixel(1, 0, 2)) + self.assertFalse(self.screen.get_pixel(2, 0, 2)) + self.assertTrue(self.screen.get_pixel(3, 0, 2)) + self.assertFalse(self.screen.get_pixel(4, 0, 2)) + self.assertTrue(self.screen.get_pixel(5, 0, 2)) + self.assertFalse(self.screen.get_pixel(6, 0, 2)) + self.assertTrue(self.screen.get_pixel(7, 0, 2)) + self.assertTrue(self.screen.get_pixel(8, 0, 2)) + self.assertFalse(self.screen.get_pixel(9, 0, 2)) + self.assertTrue(self.screen.get_pixel(10, 0, 2)) + self.assertFalse(self.screen.get_pixel(11, 0, 2)) + self.assertTrue(self.screen.get_pixel(12, 0, 2)) + self.assertFalse(self.screen.get_pixel(13, 0, 2)) + self.assertTrue(self.screen.get_pixel(14, 0, 2)) + self.assertFalse(self.screen.get_pixel(15, 0, 2)) + def test_draw_sprite_draws_correct_sprite(self): screen = Chip8Screen(2) screen.init_display()