mirror of
https://github.com/KrisKennaway/ii-vision.git
synced 2025-07-01 23:24:47 +00:00
Update comments and fix some bugs
make_edit_distance - use MASKED_DOTS since it does not have a simple relationship to the HEADER_BITS/BODY_BITS for HGR - try disabling transposition distances for Damerau-Levenshtein, this may give better quality screen - introduce separate notion of MASKED_DOTS which is the number of (coloured) pixels we can extract from MASKED_BITS. For HGR this is not the same. - fix bug in _fix_array_neighbours that was not fixing headers for HGR - don't cache everything in byte_pair_differences, it's effectively unbounded. Using 1M for LRU size seems to work just as well in practise, without leaking memory. - fix bug in _diff_weights when comparing content, we want to evaluate the effect of storing content byte in each offset separately, not cumulatively. - add a consistency check function (not currently wired up) to assert that headers/footers are in sync across columns - HGR should have 16 body bits, this was causing headers not to propagate correctly to/from neighbouring column - add test case for this bug video - Use 8 random bits consistently, using 16 in some places may have introduced bias - ignore palette bit when comparing 0x00 and 0x7f in sanity check
This commit is contained in:
@ -1,7 +1,8 @@
|
||||
"""Apple II nominal display colours, represented by 4-bit dot sequences.
|
||||
|
||||
These are distinct from the effective colours that are actually displayed,
|
||||
e.g. due to white/black coalescing and NTSC artifacting.
|
||||
These are the "asymptotic" colours as displayed in e.g. continuous runs of
|
||||
pixels. The effective colours that are actually displayed are not discrete,
|
||||
due to NTSC artifacting being a continuous process.
|
||||
"""
|
||||
|
||||
from typing import Tuple, Type
|
||||
@ -10,6 +11,66 @@ import enum
|
||||
import functools
|
||||
|
||||
|
||||
class NominalColours(enum.Enum):
|
||||
pass
|
||||
|
||||
|
||||
class HGRColours(NominalColours):
|
||||
"""Map from 4-bit dot representation to DHGR pixel colours.
|
||||
|
||||
Dots are in memory bit order (MSB -> LSB), which is opposite to screen
|
||||
order (LSB -> MSB is ordered left-to-right on the screen)
|
||||
|
||||
Note that these are right-rotated from the HGR mapping, because of a
|
||||
1-tick phase difference in the colour reference signal for DHGR vs HGR
|
||||
"""
|
||||
BLACK = 0b0000
|
||||
MAGENTA = 0b0001
|
||||
BROWN = 0b1000
|
||||
ORANGE = 0b1001 # HGR colour
|
||||
DARK_GREEN = 0b0100
|
||||
GREY1 = 0b0101
|
||||
GREEN = 0b1100 # HGR colour
|
||||
YELLOW = 0b1101
|
||||
DARK_BLUE = 0b0010
|
||||
VIOLET = 0b0011 # HGR colour
|
||||
GREY2 = 0b1010
|
||||
PINK = 0b1011
|
||||
MED_BLUE = 0b0110 # HGR colour
|
||||
LIGHT_BLUE = 0b0111
|
||||
AQUA = 0b1110
|
||||
WHITE = 0b1111
|
||||
|
||||
|
||||
class DHGRColours(NominalColours):
|
||||
"""Map from 4-bit dot representation to DHGR pixel colours.
|
||||
|
||||
Dots are in memory bit order (MSB -> LSB), which is opposite to screen
|
||||
order (LSB -> MSB is ordered left-to-right on the screen)
|
||||
|
||||
Note that these are right-rotated from the HGR mapping, because of a
|
||||
1-tick phase difference in the colour reference signal for DHGR vs HGR
|
||||
"""
|
||||
|
||||
# representation.
|
||||
BLACK = 0b0000
|
||||
MAGENTA = 0b1000
|
||||
BROWN = 0b0100
|
||||
ORANGE = 0b1100 # HGR colour
|
||||
DARK_GREEN = 0b0010
|
||||
GREY1 = 0b1010
|
||||
GREEN = 0b0110 # HGR colour
|
||||
YELLOW = 0b1110
|
||||
DARK_BLUE = 0b0001
|
||||
VIOLET = 0b1001 # HGR colour
|
||||
GREY2 = 0b0101
|
||||
PINK = 0b1101
|
||||
MED_BLUE = 0b0011 # HGR colour
|
||||
LIGHT_BLUE = 0b1011
|
||||
AQUA = 0b0111
|
||||
WHITE = 0b1111
|
||||
|
||||
|
||||
def ror(int4: int, howmany: int) -> int:
|
||||
"""Rotate-right an int4 some number of times."""
|
||||
res = int4
|
||||
@ -36,52 +97,6 @@ def _rol(int4: int) -> int:
|
||||
return ((int4 & 0b0111) << 1) ^ ((int4 & 0b1000) >> 3)
|
||||
|
||||
|
||||
class NominalColours(enum.Enum):
|
||||
pass
|
||||
|
||||
|
||||
class HGRColours(NominalColours):
|
||||
# Value is memory bit order, which is opposite to screen order (bits
|
||||
# ordered Left to Right on screen)
|
||||
BLACK = 0b0000
|
||||
MAGENTA = 0b0001
|
||||
BROWN = 0b1000
|
||||
ORANGE = 0b1001 # HGR colour
|
||||
DARK_GREEN = 0b0100
|
||||
GREY1 = 0b0101
|
||||
GREEN = 0b1100 # HGR colour
|
||||
YELLOW = 0b1101
|
||||
DARK_BLUE = 0b0010
|
||||
VIOLET = 0b0011 # HGR colour
|
||||
GREY2 = 0b1010
|
||||
PINK = 0b1011
|
||||
MED_BLUE = 0b0110 # HGR colour
|
||||
LIGHT_BLUE = 0b0111
|
||||
AQUA = 0b1110
|
||||
WHITE = 0b1111
|
||||
|
||||
|
||||
class DHGRColours(NominalColours):
|
||||
# DHGR 4-bit memory representation is right-rotated from the HGR video
|
||||
# representation.
|
||||
BLACK = 0b0000
|
||||
MAGENTA = 0b1000
|
||||
BROWN = 0b0100
|
||||
ORANGE = 0b1100 # HGR colour
|
||||
DARK_GREEN = 0b0010
|
||||
GREY1 = 0b1010
|
||||
GREEN = 0b0110 # HGR colour
|
||||
YELLOW = 0b1110
|
||||
DARK_BLUE = 0b0001
|
||||
VIOLET = 0b1001 # HGR colour
|
||||
GREY2 = 0b0101
|
||||
PINK = 0b1101
|
||||
MED_BLUE = 0b0011 # HGR colour
|
||||
LIGHT_BLUE = 0b1011
|
||||
AQUA = 0b0111
|
||||
WHITE = 0b1111
|
||||
|
||||
|
||||
@functools.lru_cache(None)
|
||||
def dots_to_nominal_colour_pixels(
|
||||
num_bits: int,
|
||||
@ -92,10 +107,10 @@ def dots_to_nominal_colour_pixels(
|
||||
"""Sequence of num_bits nominal colour pixels via sliding 4-bit window.
|
||||
|
||||
Includes the 3-bit header that represents the trailing 3 bits of the
|
||||
previous tuple body. i.e. storing a byte in aux even columns will also
|
||||
influence the colours of the previous main odd column.
|
||||
previous tuple body. e.g. for DHGR, storing a byte in aux even columns
|
||||
will also influence the colours of the previous main odd column.
|
||||
|
||||
This naively models the NTSC colour artifacting.
|
||||
This naively models (approximates) the NTSC colour artifacting.
|
||||
|
||||
TODO: Use a more careful analogue colour composition model to produce
|
||||
effective pixel colours.
|
||||
@ -126,6 +141,8 @@ def dots_to_nominal_colour_pixel_values(
|
||||
colours: Type[NominalColours],
|
||||
init_phase: int = 1 # Such that phase = 0 at start of body
|
||||
) -> Tuple[int]:
|
||||
""""Sequence of num_bits nominal colour values via sliding 4-bit window."""
|
||||
|
||||
return tuple(p.value for p in dots_to_nominal_colour_pixels(
|
||||
num_bits, dots, colours, init_phase
|
||||
))
|
||||
|
Reference in New Issue
Block a user