diff --git a/assets/disk0/tvdos/bin/playtav.js b/assets/disk0/tvdos/bin/playtav.js index 184da39..53b728b 100644 --- a/assets/disk0/tvdos/bin/playtav.js +++ b/assets/disk0/tvdos/bin/playtav.js @@ -112,7 +112,8 @@ if (fullFilePathStr.startsWith('$:/TAPE') || fullFilePathStr.startsWith('$:\\TAP con.clear() con.curs_set(0) -graphics.setGraphicsMode(5) // 32-bit colour mode +graphics.setGraphicsMode(4) // initially set to 4bpp mode +graphics.setGraphicsMode(5) // set to 8bpp mode. If GPU don't support it, mode will remain to 4 graphics.clearPixels(0) graphics.clearPixels2(0) graphics.clearPixels3(0) @@ -394,31 +395,27 @@ let decodeTime = 0 let uploadTime = 0 let biasTime = 0 +const nativeWidth = graphics.getPixelDimension()[0] +const nativeHeight = graphics.getPixelDimension()[1] const BIAS_LIGHTING_MIN = 1.0 / 16.0 let oldBgcol = [BIAS_LIGHTING_MIN, BIAS_LIGHTING_MIN, BIAS_LIGHTING_MIN] let notifHidden = false function getRGBfromScr(x, y) { - if (gpuGraphicsMode == 4) { - let offset = y * WIDTH + x - let rg = sys.peek(-1048577 - offset) - let ba = sys.peek(-1310721 - offset) - return [(rg >>> 4) / 15.0, (rg & 15) / 15.0, (ba >>> 4) / 15.0] - } - else if (gpuGraphicsMode == 5) { - let offset = y * WIDTH + x - let r = sys.peek(-1048577 - offset) - let g = sys.peek(-1310721 - offset) - let b = sys.peek(-1572865 - offset) - return [r / 255.0, g / 255.0, b / 255.0] - } + let offset = y * WIDTH + x + let fb1 = sys.peek(-1048577 - offset) + let fb2 = sys.peek(-1310721 - offset) + let fb3 = sys.peek(-1310721 - (262144 * (gpuGraphicsMode - 4)) - offset) + + if (gpuGraphicsMode == 4) + return [(fb1 >>> 4) / 15.0, (fb1 & 15) / 15.0, (fb2 >>> 4) / 15.0] + else + return [fb1 / 255.0, fb2 / 255.0, fb3 / 255.0] } function setBiasLighting() { let samples = [] - let nativeWidth = graphics.getPixelDimension()[0] - let nativeHeight = graphics.getPixelDimension()[1] let width = header.width; let height = header.height let offsetX = Math.floor((nativeWidth - width) / 2) diff --git a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt index 047899c..a534887 100644 --- a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt @@ -1477,28 +1477,24 @@ class GraphicsJSR223Delegate(private val vm: VM) { // Get native resolution val nativeWidth = gpu.config.width val nativeHeight = gpu.config.height - val totalNativePixels = (nativeWidth * nativeHeight) + val totalNativePixels = nativeWidth * nativeHeight val totalVideoPixels = width * height - val chunkSize = 32768 + val chunkSize = width val rgbBulkBuffer = ByteArray(chunkSize * 3) val rgChunk = ByteArray(chunkSize) val baChunk = ByteArray(chunkSize) val rChunk = ByteArray(chunkSize) val gChunk = ByteArray(chunkSize) val bChunk = ByteArray(chunkSize) - val aChunk = ByteArray(chunkSize); aChunk.fill(-1) + val aChunk = ByteArray(chunkSize) var pixelsProcessed = 0 // Helper function to write chunks to framebuffer (shared between native size and resize paths) - fun writeChunksToFramebuffer( - pixelsInChunk: Int, - rgChunk: ByteArray, baChunk: ByteArray, - rChunk: ByteArray, gChunk: ByteArray, bChunk: ByteArray, aChunk: ByteArray - ) { + fun writeChunksToFramebuffer(pixelsInChunk: Int, startX: Int = 0, startY: Int = 0) { val pixelIndex = pixelsProcessed - val videoY = pixelIndex / width - val videoX = pixelIndex % width + val videoY = (pixelIndex / width) + startY + val videoX = (pixelIndex % width) + startX val nativePos = videoY * nativeWidth + videoX if (graphicsMode == 4) { UnsafeHelper.memcpyRaw( @@ -1510,7 +1506,7 @@ class GraphicsJSR223Delegate(private val vm: VM) { null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong() ) } - else if (graphicsMode == 5) { + else { UnsafeHelper.memcpyRaw( rChunk, UnsafeHelper.getArrayOffset(rChunk), null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong() @@ -1532,7 +1528,7 @@ class GraphicsJSR223Delegate(private val vm: VM) { pixelsProcessed += pixelsInChunk } - fun writeToChunk(r: Int, g: Int, b: Int, videoX: Int, videoY: Int, i: Int) { + fun writeToChunk(r: Int, g: Int, b: Int, videoX: Int, videoY: Int, i: Int, coordInVideoFrame: Boolean = true) { if (graphicsMode == 4) { // Apply Bayer dithering and convert to 4-bit val r4 = ditherValue(r, videoX, videoY, frameCount) @@ -1541,13 +1537,14 @@ class GraphicsJSR223Delegate(private val vm: VM) { // Pack RGB values and store in chunk arrays for batch processing rgChunk[i] = ((r4 shl 4) or g4).toByte() - baChunk[i] = ((b4 shl 4) or 15).toByte() + baChunk[i] = ((b4 shl 4) or coordInVideoFrame.toInt().times(15)).toByte() } - else if (graphicsMode == 5) { + else { rChunk[i] = r.toByte() gChunk[i] = g.toByte() bChunk[i] = b.toByte() + aChunk[i] = coordInVideoFrame.toInt().times(255).toByte() } } @@ -1574,7 +1571,7 @@ class GraphicsJSR223Delegate(private val vm: VM) { } // Write chunks to framebuffer - writeChunksToFramebuffer(pixelsInChunk, rgChunk, baChunk, rChunk, gChunk, bChunk, aChunk) + writeChunksToFramebuffer(pixelsInChunk) } } else if (resizeToFull && (width / 2 != nativeWidth / 2 || height / 2 != nativeHeight / 2)) { @@ -1605,7 +1602,7 @@ class GraphicsJSR223Delegate(private val vm: VM) { } // Write chunks to framebuffer - writeChunksToFramebuffer(pixelsInChunk, rgChunk, baChunk, rChunk, gChunk, bChunk, aChunk) + writeChunksToFramebuffer(pixelsInChunk) } } else { // Optimised centering logic with bulk memory operations @@ -1633,18 +1630,17 @@ class GraphicsJSR223Delegate(private val vm: VM) { if (nativeX !in 0 until nativeWidth || nativeY !in 0 until nativeHeight) { continue } - - // Read RGB values from bulk buffer - val rgbIndex = i * 3 - val r = rgbBulkBuffer[rgbIndex].toUint() - val g = rgbBulkBuffer[rgbIndex + 1].toUint() - val b = rgbBulkBuffer[rgbIndex + 2].toUint() - writeToChunk(r, g, b, videoX, videoY, i) + // Read RGB values from bulk buffer + val r = rgbBulkBuffer[i*3].toUint() + val g = rgbBulkBuffer[i*3 + 1].toUint() + val b = rgbBulkBuffer[i*3 + 2].toUint() + + writeToChunk(r, g, b, nativeX, nativeY, i) } // Write chunks to framebuffer - writeChunksToFramebuffer(pixelsInChunk, rgChunk, baChunk, rChunk, gChunk, bChunk, aChunk) + writeChunksToFramebuffer(pixelsInChunk, offsetX, offsetY) } } }