mirror of
https://github.com/KrisKennaway/ii-vision.git
synced 2025-07-15 05:24:39 +00:00
Checkpoint WIP for easier comparison to dhgr branch:
- naive version of NTSC artifacting, it uses a sliding 4-bit window to assign a nominal (D)HGR colour to each dot position. A more sophisticated/correct implementation would model the YIQ signal directly. - Switch DHGRBitmap implementation to use a 34-bit representation of the 4-byte tuple, comprised of a 3-bit header and footer, plus 4*7=28-bit body. The headers/footers account for the influence on neighbouring tuples from the 4-bit NTSC window. - With this model each screen byte influences 13 pixels, so we need to precompute 2^26 edit distances for all possible (source, target) 13-bit sequences. - Checkpointing not-yet-working HGR implementation. - Add new unit tests but not yet all passing due to refactoring
This commit is contained in:
@ -4,6 +4,7 @@ import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import colours
|
||||
import screen
|
||||
|
||||
|
||||
@ -184,5 +185,411 @@ class TestDHGRBitmap(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
def binary(a):
|
||||
return np.vectorize("{:032b}".format)(a)
|
||||
|
||||
|
||||
class TestHGRBitmap(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.main = screen.MemoryMap(screen_page=1)
|
||||
|
||||
def test_pixel_packing_p0_p0(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b01000011
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b01000011
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b1100000000111111000000001111
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
def test_pixel_packing_p0_p1(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b01000011
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b11000011
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b1000000001111111000000001111
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
def test_pixel_packing_p1_p0(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11000011
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b01000011
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b1100000000111110000000011110
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
def test_pixel_packing_p1_p1(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11000011
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b11000011
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b1000000001111110000000011110
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
def test_pixel_packing_p1_promote_p0(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b00000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b01000000
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 2] = 0b10000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b0000000000000000000000000001
|
||||
got = hgr.packed[0, 1]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
def test_pixel_packing_p1_promote_p1(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b00000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b11000000
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 2] = 0b10000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b0000000000000000000000000001
|
||||
got = hgr.packed[0, 1]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
def testNominalColours(self):
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b01010101
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00101010
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 2] = 0b01010101
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b000110011001100110011001100110011
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.VIOLET,
|
||||
),
|
||||
colours.int34_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
# See Figure 8.15 from Sather, "Understanding the Apple IIe"
|
||||
|
||||
def testNominalColoursSather1(self):
|
||||
# Extend violet into light blue
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b01000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b10000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.LIGHT_BLUE,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather2(self):
|
||||
# Cut off blue with black to produce dark blue
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.DARK_BLUE,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather3(self):
|
||||
# Cut off blue with green to produce aqua
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00000001
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.AQUA,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather4(self):
|
||||
# Cut off white with black to produce pink
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11100000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b0000000000000011100000000000
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
# TODO: BROWN(0001)/VIOLET(1100) should reframe to PINK (1011)
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BROWN,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather5(self):
|
||||
# Extend green into light brown
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b01000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b10000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b0000000000000111000000000000
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
# TODO: LIGHT_BLUE should reframe to PINK (1011)
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.LIGHT_BLUE,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather6(self):
|
||||
# Cut off orange with black to produce dark brown
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b00000000000000010000000000000
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
# TODO: DARK_BLUE should reframe to DARK_BROWN
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.DARK_BLUE,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather7(self):
|
||||
# Cut off orange with violet to produce pink
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11000000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00000001
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b00000000000001110000000000000
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
# TODO: AQUA should reframe to PINK
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.AQUA,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(hgr.packed[0, 0],
|
||||
colours.HGRColours)
|
||||
)
|
||||
|
||||
def testNominalColoursSather8(self):
|
||||
# Cut off white with black to produce aqua
|
||||
|
||||
# PDCCBBAA
|
||||
self.main.page_offset[0, 0] = 0b11100000
|
||||
# PGGFFEED
|
||||
self.main.page_offset[0, 1] = 0b00000000
|
||||
|
||||
hgr = screen.HGRBitmap(
|
||||
main_memory=self.main)
|
||||
|
||||
want = 0b00000000000000011100000000000
|
||||
got = hgr.packed[0, 0]
|
||||
|
||||
self.assertEqual(
|
||||
want, got, "\n%s\n%s" % (binary(want), binary(got))
|
||||
)
|
||||
|
||||
# TODO: BROWN/VIOLET should reframe to AQUA
|
||||
self.assertEqual(
|
||||
(
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BROWN,
|
||||
colours.HGRColours.VIOLET,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
colours.HGRColours.BLACK,
|
||||
),
|
||||
colours.int28_to_nominal_colour_pixels(
|
||||
hgr.packed[0, 0], colours.HGRColours)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Reference in New Issue
Block a user