mirror of
https://github.com/schibo/1964js.git
synced 2025-04-02 10:52:54 -04:00
182 lines
7.3 KiB
CoffeeScript
182 lines
7.3 KiB
CoffeeScript
###1964js - JavaScript/HTML5 port of 1964 - N64 emulator
|
|
Copyright (C) 2012 Joel Middendorf
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.###
|
|
|
|
useExternalTextures = false #for loading community texture packs
|
|
|
|
C1964jsRenderer = (settings, glx, webGL) ->
|
|
gl = glx
|
|
texrectVertexPositionBuffer = undefined
|
|
texrectVertexTextureCoordBuffer = undefined
|
|
texrectVertexIndexBuffer = undefined
|
|
@videoHLE = undefined
|
|
fivetoeight = [0x00,0x08,0x10,0x18,0x21,0x29,0x31,0x39,0x42,0x4A,0x52,0x5A,0x63,0x6B,0x73,0x7B,0x84,0x8C,0x94,0x9C,0xA5,0xAD,0xB5,0xBD,0xC6,0xCE,0xD6,0xDE,0xE7,0xEF,0xF7,0xFF]
|
|
@textureCache = new Object()
|
|
|
|
@texRect = (xl, yl, xh, yh, s, t, dsdx, dtdy, tile, tmem, videoHLE) ->
|
|
|
|
@videoHLE = videoHLE
|
|
|
|
canvaswidth = videoHLE.pow2roundup tile.width
|
|
canvasheight = videoHLE.pow2roundup tile.height
|
|
|
|
widthscale = tile.width / canvaswidth
|
|
heightscale = tile.height / canvasheight
|
|
|
|
rectWidth = xh-xl
|
|
rectHeight = yh-yl
|
|
|
|
#console.log "Rectsize:"+rectWidth+"x"+rectHeight+" S:"+s+"("+dsdx+") T:"+t+"("+dtdy
|
|
|
|
sl = s / tile.height
|
|
tl = t / tile.width
|
|
sh = (s + (rectWidth*dsdx)) / tile.width * widthscale
|
|
th = (t + (rectHeight*dtdy)) / tile.height * heightscale
|
|
|
|
xl = (xl-160)/160
|
|
xh = (xh-160)/160
|
|
yl = -(yl-120)/120
|
|
yh = -(yh-120)/120
|
|
|
|
initQuad xl, yl, xh, yh, sl, tl, sh, th, videoHLE
|
|
@draw tile, tmem, videoHLE
|
|
return
|
|
|
|
@formatTexture = (tile, tmem, cw, ch) ->
|
|
canvaswidth = cw
|
|
canvasheight = ch
|
|
|
|
texturesize = canvasheight * canvaswidth * 4
|
|
#hacky texture cache unique id (want to see how fast we currently are)
|
|
|
|
@useTextureCache = true #change to true to try texture cache
|
|
if @useTextureCache is true
|
|
randomPixel = canvasheight * canvaswidth
|
|
textureId = (tmem[randomPixel]>>>0) << 24 | (tmem[randomPixel+canvaswidth+1]>>>0) << 16 | (tmem[randomPixel+canvaswidth*2+1]>>>0) << 8 | tmem[randomPixel+canvaswidth*3+1]>>>0
|
|
return @textureCache[textureId] if @textureCache[textureId]?
|
|
|
|
buffer = new ArrayBuffer(texturesize)
|
|
texture = new Uint8Array(buffer)
|
|
|
|
if @useTextureCache is true
|
|
@textureCache[textureId] = texture
|
|
switch tile.fmt
|
|
when 0
|
|
switch tile.siz
|
|
when 2
|
|
width = tile.width;
|
|
j=0
|
|
while j < tile.height
|
|
i=0
|
|
while i < tile.width
|
|
base2 = (j*width*2) + (i*2)
|
|
base4 = (j*canvaswidth*4) + (i*4)
|
|
color16 = tmem[base2]<<8 | tmem[base2+1]
|
|
texture[base4] = fivetoeight[color16 >> 11 & 0x1F]
|
|
texture[base4 + 1] = fivetoeight[color16 >> 6 & 0x1F]
|
|
texture[base4 + 2] = fivetoeight[color16 >> 1 & 0x1F]
|
|
texture[base4 + 3] = if color16 & 0x01 == 0 then 0x00 else 0xFF
|
|
i++
|
|
j++
|
|
|
|
# if @useTextureCache is true
|
|
# return @textureCache[textureId]
|
|
return texture
|
|
|
|
initQuad = (xl, yl, xh, yh, sl, tl, sh, th, videoHLE) ->
|
|
|
|
vertices = [xh, yh, 0.0, xh, yl, 0.0, xl, yl, 0.0, xl, yh, 0.0]
|
|
texrectVertexPositionBuffer = gl.createBuffer()
|
|
gl.bindBuffer gl.ARRAY_BUFFER, texrectVertexPositionBuffer
|
|
gl.bufferData gl.ARRAY_BUFFER, new Float32Array(vertices), gl.DYNAMIC_DRAW
|
|
texrectVertexPositionBuffer.itemSize = 3
|
|
texrectVertexPositionBuffer.numItems = 4
|
|
|
|
textureCoords = [sh, th, sh, tl, sl, tl, sl, th]
|
|
texrectVertexTextureCoordBuffer = gl.createBuffer()
|
|
gl.bindBuffer gl.ARRAY_BUFFER, texrectVertexTextureCoordBuffer
|
|
gl.bufferData gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW
|
|
texrectVertexTextureCoordBuffer.itemSize = 2
|
|
texrectVertexTextureCoordBuffer.numItems = 4
|
|
|
|
texrectVertexIndices = [0, 1, 2, 0, 2, 3]
|
|
texrectVertexIndexBuffer = gl.createBuffer()
|
|
gl.bindBuffer gl.ELEMENT_ARRAY_BUFFER, texrectVertexIndexBuffer
|
|
gl.bufferData gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(texrectVertexIndices), gl.STATIC_DRAW
|
|
texrectVertexIndexBuffer.itemSize = 1
|
|
texrectVertexIndexBuffer.numItems = 6
|
|
|
|
return
|
|
|
|
|
|
@draw = (tile, tmem, videoHLE) ->
|
|
gl.useProgram webGL.shaderProgram
|
|
|
|
# basic settings
|
|
gl.disable gl.DEPTH_TEST
|
|
gl.enable gl.BLEND
|
|
gl.blendFunc gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA
|
|
|
|
gl.enableVertexAttribArray webGL.shaderProgram.vertexPositionAttribute
|
|
gl.bindBuffer gl.ARRAY_BUFFER, texrectVertexPositionBuffer
|
|
gl.vertexAttribPointer webGL.shaderProgram.vertexPositionAttribute, texrectVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0
|
|
|
|
gl.enableVertexAttribArray webGL.shaderProgram.textureCoordAttribute
|
|
gl.bindBuffer gl.ARRAY_BUFFER, texrectVertexTextureCoordBuffer
|
|
gl.vertexAttribPointer webGL.shaderProgram.textureCoordAttribute, texrectVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0
|
|
|
|
canvaswidth = videoHLE.pow2roundup tile.width
|
|
canvasheight = videoHLE.pow2roundup tile.height
|
|
#console.log "Binding Texture Size: "+tile.width+" x "+tile.height+" -> "+canvaswidth+" x "+canvasheight
|
|
|
|
texture = @formatTexture(tile, tmem, canvaswidth, canvasheight)
|
|
if texture isnt undefined
|
|
colorsTexture = gl.createTexture()
|
|
gl.activeTexture(gl.TEXTURE0)
|
|
gl.bindTexture(gl.TEXTURE_2D, colorsTexture)
|
|
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, canvaswidth, canvasheight, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture)
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
|
gl.uniform1i webGL.shaderProgram.samplerUniform, colorsTexture
|
|
|
|
if videoHLE.primColor.length > 0
|
|
gl.uniform4fv webGL.shaderProgram.uPrimColor, videoHLE.primColor
|
|
|
|
if videoHLE.fillColor.length > 0
|
|
gl.uniform4fv webGL.shaderProgram.uFillColor, videoHLE.fillColor
|
|
|
|
if videoHLE.blendColor.length > 0
|
|
gl.uniform4fv webGL.shaderProgram.uBlendColor, videoHLE.blendColor
|
|
|
|
if videoHLE.envColor.length > 0
|
|
gl.uniform4fv webGL.shaderProgram.uEnvColor, videoHLE.envColor
|
|
|
|
gl.bindBuffer gl.ELEMENT_ARRAY_BUFFER, texrectVertexIndexBuffer
|
|
webGL.setMatrixUniforms webGL.shaderProgram
|
|
webGL.setCombineUniforms webGL.shaderProgram
|
|
gl.uniform1i webGL.shaderProgram.wireframeUniform, if settings.wireframe then 1 else 0
|
|
|
|
if settings.wireframe is true
|
|
gl.drawElements gl.LINE_LOOP, texrectVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0
|
|
else
|
|
gl.drawElements gl.TRIANGLES, texrectVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0
|
|
|
|
return
|
|
return this
|
|
#hack global space until we export classes properly
|
|
#node.js uses exports; browser uses this (window)
|
|
root = exports ? this
|
|
root.C1964jsRenderer = C1964jsRenderer
|