/**
 * Represents the ZX 48K ULA screen. (0x4000-0x5AFF)
 * I.e. it takes a bank and converts it to a gif image.
 */ class UlaScreen { public static SCREEN_HEIGHT = 192 ; public static SCREEN_WIDTH = 256 ; protected static zxPalette = [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xD7 , 0xD7 , 0x00 , 0x00 , 0xD7 , 0x00 , 0xD7 , 0x00 , 0xD7 , 0x00 , 0x00 , 0xD7 , 0xD7 , 0xD7 , 0xD7 , 0x00 , 0xD7 , 0xD7 , 0xD7 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x00 , 0x00 , 0xFF , 0x00 , 0xFF , 0x00 , 0xFF , 0x00 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0x00 , 0xFF , 0xFF , 0xFF , ] ; param ctx param imgData param ulaScreen param time public static drawUlaScreen ( ctx , imgData , ulaScreen , time = 0 ) { const interval = 625 ; const remainder = time % interval ; const flash = ( remainder >= interval / 2 ) ? 0x80 : 0 ; const colorStart = UlaScreen . SCREEN_HEIGHT * UlaScreen . SCREEN_WIDTH / 8 ; const pixels = imgData . data ; let pixelIndex = 0 ; let inIndex = 0 ; let colorIndex = 0 ; const width8 = UlaScreen . SCREEN_WIDTH / 8 ; const height = UlaScreen . SCREEN_HEIGHT ; colorIndex = colorStart ; for ( let y = 0 ; y < height ; y += 8 ) { inIndex = ( ( y & 192 ) * 32 ) + ( ( y & 56 ) * 4 ) ; for ( let x = 0 ; x < width8 ; x ++ ) { let color = ulaScreen [ colorIndex ] ; const cIndexBase = ( color & 0x40 ) / 8 ; pixelIndex = ( y * 256 + x * 8 ) * 4 ; for ( let y2 = 0 ; y2 < 8 ; y2 ++ ) { let byteValue = ulaScreen [ inIndex + y2 * 256 ] ; if ( color & flash ) { byteValue ^= 255 ; } let mask = 128 ; while ( mask >= 1 ) { let value = byteValue & mask ; let cIndex = cIndexBase ; if ( value ) { cIndex += color & 7 ; } else { cIndex += ( color / 8 ) & 7 ; } cIndex *= 3 ; pixels [ pixelIndex ++ ] = this . zxPalette [ cIndex ++ ] ; pixels [ pixelIndex ++ ] = this . zxPalette [ cIndex ++ ] ; pixels [ pixelIndex ++ ] = this . zxPalette [ cIndex ] ; pixels [ pixelIndex ++ ] = 255 ; mask /= 2 ; } pixelIndex += 992 ; } inIndex ++ ; colorIndex ++ ; } } ctx . putImageData ( imgData , 0 , 0 ) ; } param zxColor returns public static getHtmlColor ( zxColor ) { let i = 3 * zxColor ; let htmlColor = '#' ; for ( let k = 0 ; k < 3 ; k ++ ) { const value = this . zxPalette [ i ++ ] ; htmlColor += value . toString ( 16 ) . padStart ( 2 , '0' ) ; } return htmlColor ; } }