116 lines
4 KiB
CoffeeScript
116 lines
4 KiB
CoffeeScript
|
|
class @ImageTextMode
|
||
|
|
|
||
|
|
@VERSION = '0.01'
|
||
|
|
|
||
|
|
constructor: ( options ) ->
|
||
|
|
@screen = []
|
||
|
|
@palette = new ImageTextModePaletteVGA()
|
||
|
|
@font = new ImageTextModeFont8x16()
|
||
|
|
@[k] = v for own k, v of options
|
||
|
|
|
||
|
|
parseUrl: ( url ) ->
|
||
|
|
req = new XMLHttpRequest()
|
||
|
|
req.open 'GET', url, false
|
||
|
|
req.overrideMimeType 'text/plain; charset=x-user-defined'
|
||
|
|
req.send null
|
||
|
|
content = if req.status is 200 or req.status is 0 then req.responseText else ''
|
||
|
|
@parse content
|
||
|
|
|
||
|
|
unpackShort: ( data ) ->
|
||
|
|
shrt = ( @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 0 )
|
||
|
|
if shrt < 0
|
||
|
|
shrt += 65536
|
||
|
|
shrt
|
||
|
|
|
||
|
|
unpackLong: ( data ) ->
|
||
|
|
lng = ((( @getByteAt( data, 0 ) << 8 ) + @getByteAt( data, 1 ) << 8 ) + @getByteAt( data, 2 ) << 8 ) + @getByteAt( data, 3 )
|
||
|
|
if lng < 0
|
||
|
|
lng += 4294967296
|
||
|
|
lng
|
||
|
|
|
||
|
|
getByteAt: ( data, offset ) ->
|
||
|
|
data.charCodeAt( offset ) & 0xFF
|
||
|
|
|
||
|
|
# could we replace this with math.max ? Not worth it,called once per view
|
||
|
|
# we COULD, but we'd do some crap like "Math.max.apply(null,blah) and that's not readable"
|
||
|
|
getWidth: ->
|
||
|
|
max = 0
|
||
|
|
for y in [ 0 .. @screen.length - 1 ]
|
||
|
|
max = @screen[ y ].length if @screen[ y ]? && @screen[ y ].length > max
|
||
|
|
max
|
||
|
|
|
||
|
|
getHeight: ->
|
||
|
|
@screen.length
|
||
|
|
|
||
|
|
parsePaletteData: ( data ) ->
|
||
|
|
colors = []
|
||
|
|
for i in [ 0 .. 45 ] by 3
|
||
|
|
r = @getByteAt( data, i )
|
||
|
|
r = r << 2 | r >> 4
|
||
|
|
g = @getByteAt( data, i + 1 )
|
||
|
|
g = g << 2 | g >> 4
|
||
|
|
b = @getByteAt( data, i + 2 )
|
||
|
|
b = b << 2 | b >> 4
|
||
|
|
colors.push [ r, g, b ]
|
||
|
|
|
||
|
|
@palette = new ImageTextModePalette( colors: colors )
|
||
|
|
|
||
|
|
parseFontData: ( data, height = 16 ) ->
|
||
|
|
chars = []
|
||
|
|
for i in [ 0 ... data.length / height ]
|
||
|
|
chr = []
|
||
|
|
for j in [ 0 ... height ]
|
||
|
|
chr.push @getByteAt( data, i * height + j )
|
||
|
|
chars.push chr
|
||
|
|
@font = new ImageTextModeFont( { chars: chars, height: height } )
|
||
|
|
|
||
|
|
# the majority of time is spent in this routine
|
||
|
|
# list comprehension seems to speed up from 1.8 seconds to 1.29 seconds from first comprehension / cleanup?
|
||
|
|
|
||
|
|
renderCanvas: ( canvasElem ) ->
|
||
|
|
w = @getWidth() * @font.width
|
||
|
|
h = @getHeight() * @font.height
|
||
|
|
|
||
|
|
canvas = document.createElement 'canvas'
|
||
|
|
canvas.setAttribute 'width', w
|
||
|
|
canvas.setAttribute 'height', h
|
||
|
|
ctx = canvas.getContext '2d'
|
||
|
|
|
||
|
|
for cy in [ 0 ... @screen.length ]
|
||
|
|
if @screen[ cy ]?
|
||
|
|
for cx in [ 0 ... @screen[ cy ].length ]
|
||
|
|
pixel = @screen[ cy ][ cx ]
|
||
|
|
curfillstyle = null
|
||
|
|
if pixel?
|
||
|
|
if pixel.attr?
|
||
|
|
fg = pixel.attr & 15
|
||
|
|
bg = ( pixel.attr & 240 ) >> 4
|
||
|
|
else
|
||
|
|
fg = pixel.fg
|
||
|
|
bg = pixel.bg
|
||
|
|
|
||
|
|
px = cx * @font.width
|
||
|
|
py = cy * @font.height
|
||
|
|
|
||
|
|
ctx.fillStyle = @palette.toRgbaString( @palette.colors[ bg ] )
|
||
|
|
ctx.fillRect px, py, @font.width, @font.height
|
||
|
|
|
||
|
|
ctx.fillStyle = @palette.toRgbaString( @palette.colors[ fg ] )
|
||
|
|
chr = @font.chars[ pixel.ch.charCodeAt( 0 ) & 0xff ]
|
||
|
|
i = 0
|
||
|
|
for line in chr
|
||
|
|
ctx.fillRect px + j, py + i, 1, 1 for j in [ 0 ... @font.width ] when line & (1 << @font.width - 1 - j )
|
||
|
|
i += 1
|
||
|
|
|
||
|
|
canvasElem.setAttribute 'width', w
|
||
|
|
canvasElem.setAttribute 'height', h
|
||
|
|
ctx = canvasElem.getContext '2d'
|
||
|
|
ctx.drawImage canvas, 0, 0
|
||
|
|
|
||
|
|
toBinaryArray: (str) ->
|
||
|
|
buf = new ArrayBuffer(str.length * 2) # 2 bytes for each char
|
||
|
|
bufView = new Uint8Array(buf)
|
||
|
|
bufView[i] = str.charCodeAt(i) for i in [0...str.length]
|
||
|
|
buf
|
||
|
|
|