mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
arseiotnarseit
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
if (!exec_args[1]) {
|
||||
printerrln("Usage: jpdectest image.jpg")
|
||||
}
|
||||
|
||||
filesystem.open("A", exec_args[1], "R")
|
||||
|
||||
let status = com.getStatusCode(0)
|
||||
@@ -20,7 +24,8 @@ println(`dim: ${imgw}x${imgh}`)
|
||||
println(`converting to displayable format...`)
|
||||
|
||||
// convert colour
|
||||
graphics.imageToDisplayableFormat(imageData, -1048577, imgw, imgh, 4, 2)
|
||||
graphics.setGraphicsMode(0)
|
||||
graphics.imageToDisplayableFormat(imageData, -1048577, imgw, imgh, 4, 1)
|
||||
|
||||
sys.free(imageData)
|
||||
sys.free(infile)
|
||||
|
||||
31
assets/disk0/home/jpdectesthigh.js
Normal file
31
assets/disk0/home/jpdectesthigh.js
Normal file
@@ -0,0 +1,31 @@
|
||||
if (!exec_args[1]) {
|
||||
printerrln("Usage: jpdectesthigh image.jpg")
|
||||
}
|
||||
|
||||
filesystem.open("A", exec_args[1], "R")
|
||||
|
||||
let status = com.getStatusCode(0)
|
||||
let infile = undefined
|
||||
if (0 != status) return status
|
||||
|
||||
|
||||
let fileLen = filesystem.getFileLen("A")
|
||||
println(`DMA reading ${fileLen} bytes from disk...`)
|
||||
infile = sys.malloc(fileLen)
|
||||
dma.comToRam(0, 0, infile, fileLen)
|
||||
|
||||
|
||||
println("decoding")
|
||||
|
||||
// decode
|
||||
const [imgw, imgh, imageData] = graphics.decodeImageResample(infile, fileLen, -1, -1)
|
||||
|
||||
println(`dim: ${imgw}x${imgh}`)
|
||||
println(`converting to displayable format...`)
|
||||
|
||||
// convert colour
|
||||
graphics.setGraphicsMode(4)
|
||||
graphics.imageToDirectCol(imageData, -1048577, -1310721, imgw, imgh, 4, 0)
|
||||
|
||||
sys.free(imageData)
|
||||
sys.free(infile)
|
||||
@@ -366,6 +366,11 @@ Type:
|
||||
0: 256-Colour frame
|
||||
1: 256-Colour frame with palette data
|
||||
2: 4096-Colour frame (stored as two byte-planes)
|
||||
16: Series of JPEGs
|
||||
18: Series of PNGs
|
||||
20: Series of TGAs
|
||||
21: Series of TGA/GZs
|
||||
255: Every frame specifies the type
|
||||
|
||||
TYPE 0 FRAME -
|
||||
uint32 SIZE OF FRAMEDATA
|
||||
@@ -380,4 +385,13 @@ TYPE 2 FRAME -
|
||||
uint32 SIZE OF FRAMEDATA BYTE-PLANE 1
|
||||
* FRAMEDATA COMPRESSED IN GZIP
|
||||
uint32 SIZE OF FRAMEDATA BYTE-PLANE 2
|
||||
* FRAMEDATA COMPRESSED IN GZIP
|
||||
* FRAMEDATA COMPRESSED IN GZIP
|
||||
|
||||
TYPE 16+ FRAME -
|
||||
uint32 SIZE OF FRAMEDATA BYTE-PLANE 1
|
||||
* FRAMEDATA (COMPRESSED IN GZIP for TGA/GZ)
|
||||
|
||||
TYPE 255 FRAME -
|
||||
uint16 TYPE OF FRAMEDATA
|
||||
uint32 SIZE OF FRAMEDATA
|
||||
* FRAMEDATA
|
||||
@@ -361,12 +361,32 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
3f/16f,5f/16f,1f/16f,
|
||||
)
|
||||
|
||||
private val bayerKernel = intArrayOf(
|
||||
0,8,2,10,
|
||||
12,4,14,6,
|
||||
3,11,1,9,
|
||||
15,7,13,5,
|
||||
).map { (it.toFloat() + 0.5f) / 16f }.toFloatArray()
|
||||
private val bayerKernels = arrayOf(
|
||||
intArrayOf(
|
||||
0,8,2,10,
|
||||
12,4,14,6,
|
||||
3,11,1,9,
|
||||
15,7,13,5,
|
||||
),
|
||||
intArrayOf(
|
||||
8,2,10,0,
|
||||
4,14,6,12,
|
||||
11,1,9,3,
|
||||
7,13,5,15,
|
||||
),
|
||||
intArrayOf(
|
||||
7,13,5,15,
|
||||
8,2,10,0,
|
||||
4,14,6,12,
|
||||
11,1,9,3,
|
||||
),
|
||||
intArrayOf(
|
||||
15,7,13,5,
|
||||
0,8,2,10,
|
||||
12,4,14,6,
|
||||
3,11,1,9,
|
||||
)
|
||||
).map{ it.map { (it.toFloat() + 0.5f) / 16f }.toFloatArray() }
|
||||
|
||||
/**
|
||||
* This method always assume that you're using the default palette
|
||||
@@ -382,7 +402,7 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
for (k in 0L until len) {
|
||||
val x = (k % width).toInt()
|
||||
val y = (k / width).toInt()
|
||||
val t = bayerKernel[4 * (y % 4) + (x % 4)]
|
||||
val t = bayerKernels[0][4 * (y % 4) + (x % 4)]
|
||||
|
||||
val r = vm.peek(srcPtr + channels * k + 0)!!.toUint().toFloat() / 255f
|
||||
val g = vm.peek(srcPtr + channels * k + 1)!!.toUint().toFloat() / 255f
|
||||
@@ -473,4 +493,37 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
}
|
||||
|
||||
fun imageToDirectCol(srcPtr: Int, destRG: Int, destBA: Int, width: Int, height: Int, channels: Int, pattern: Int = 0) {
|
||||
val useAlpha = (channels == 4)
|
||||
val sign = if (destRG >= 0) 1 else -1
|
||||
val len = width * height
|
||||
if (destRG * destBA < 0) throw IllegalArgumentException("Both destination memories must be on the same domain (both being Usermem or HWmem)")
|
||||
|
||||
for (k in 0L until len) {
|
||||
val x = (k % width).toInt()
|
||||
val y = (k / width).toInt()
|
||||
val t = bayerKernels[pattern][4 * (y % 4) + (x % 4)]
|
||||
|
||||
val r = vm.peek(srcPtr + channels * k + 0)!!.toUint().toFloat() / 255f
|
||||
val g = vm.peek(srcPtr + channels * k + 1)!!.toUint().toFloat() / 255f
|
||||
val b = vm.peek(srcPtr + channels * k + 2)!!.toUint().toFloat() / 255f
|
||||
val a = if (useAlpha) vm.peek(srcPtr + channels * k + 3)!!.toUint().toFloat() / 255f else 1f
|
||||
|
||||
// default palette is 16-16-16 level RGB (plus 15 shades of grey)
|
||||
|
||||
val r1 = t / 15f + r
|
||||
val g1 = t / 15f + g
|
||||
val b1 = t / 15f + b
|
||||
val a1 = t / 15f + a
|
||||
|
||||
val ra = floor(15f * r1)
|
||||
val ga = floor(15f * g1)
|
||||
val ba = floor(15f * b1)
|
||||
val aa = floor(15f * a1)
|
||||
|
||||
vm.poke(destRG + k*sign, (ra.shl(4) or ga).toByte())
|
||||
vm.poke(destBA + k*sign, (ba.shl(4) or aa).toByte())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,6 +40,7 @@ data class SuperGraphicsAddonConfig(
|
||||
)
|
||||
|
||||
class ReferenceGraphicsAdapter(assetsRoot: String, vm: VM) : GraphicsAdapter(assetsRoot, vm, GraphicsAdapter.DEFAULT_CONFIG_COLOR_CRT)
|
||||
class ReferenceGraphicsAdapter2(assetsRoot: String, vm: VM) : GraphicsAdapter(assetsRoot, vm, GraphicsAdapter.DEFAULT_CONFIG_COLOR_CRT, SuperGraphicsAddonConfig(2))
|
||||
class ReferenceLikeLCD(assetsRoot: String, vm: VM) : GraphicsAdapter(assetsRoot, vm, GraphicsAdapter.DEFAULT_CONFIG_PMLCD)
|
||||
|
||||
/**
|
||||
@@ -197,7 +198,7 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
||||
val adi = addr.toInt()
|
||||
if (framebuffer2 != null) {
|
||||
return when (addr - 262144) {
|
||||
in 0 until 250880 -> framebuffer2[addr]
|
||||
in 0 until 250880 -> framebuffer2[addr - 262144]
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -222,7 +223,7 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
||||
when (addr - 262144) {
|
||||
in 0 until 250880 -> {
|
||||
lastUsedColour = byte
|
||||
framebuffer2[addr] = byte
|
||||
framebuffer2[addr - 262144] = byte
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -758,8 +759,32 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
||||
chrrom.pixels.position(0)
|
||||
|
||||
framebufferOut.setColor(-1);framebufferOut.fill()
|
||||
// if (isRefSize && graphicsMode == 4 && )
|
||||
if (isRefSize && (graphicsMode == 1 || graphicsMode == 2)) {
|
||||
if (graphicsMode == 4 && framebuffer2 != null) {
|
||||
for (y in 0 until HEIGHT) {
|
||||
var xoff = scanlineOffsets[2L * y].toUint() or scanlineOffsets[2L * y + 1].toUint().shl(8)
|
||||
if (xoff.and(0x8000) != 0) xoff = xoff or 0xFFFF0000.toInt()
|
||||
val xs = (0 + xoff).coerceIn(0, WIDTH - 1)..(WIDTH - 1 + xoff).coerceIn(0, WIDTH - 1)
|
||||
|
||||
if (xoff in -(WIDTH - 1) until WIDTH) {
|
||||
for (x in xs) {
|
||||
val rg = framebuffer[y.toLong() * WIDTH + (x - xoff)].toUint() // coerceIn not required as (x - xoff) never escapes 0..559
|
||||
val ba = framebuffer2[y.toLong() * WIDTH + (x - xoff)].toUint() // coerceIn not required as (x - xoff) never escapes 0..559
|
||||
val r = rg.ushr(4).and(15)
|
||||
val g = rg.and(15)
|
||||
val b = ba.ushr(4).and(15)
|
||||
val a = ba.and(15)
|
||||
framebufferOut.setColor(
|
||||
r.shl(28) or r.shl(24) or
|
||||
g.shl(20) or g.shl(16) or
|
||||
b.shl(12) or b.shl(8) or
|
||||
a.shl(4) or a
|
||||
)
|
||||
framebufferOut.drawPixel(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isRefSize && (graphicsMode == 1 || graphicsMode == 2)) {
|
||||
val layerOrder = (if (graphicsMode == 1) LAYERORDERS4 else LAYERORDERS2)[layerArrangement]
|
||||
for (y in 0..223) {
|
||||
var xoff = scanlineOffsets[2L * y].toUint().shl(8) or scanlineOffsets[2L * y + 1].toUint()
|
||||
|
||||
@@ -37,7 +37,7 @@ public class AppLoader {
|
||||
|
||||
String diskPath = "assets/disk0";
|
||||
|
||||
EmulInstance reference = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceGraphicsAdapter", diskPath, 560, 448);
|
||||
EmulInstance reference = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceGraphicsAdapter2", diskPath, 560, 448);
|
||||
EmulInstance reference2 = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceLikeLCD", diskPath, 560, 448);
|
||||
EmulInstance term = new EmulInstance(vm, "net.torvald.tsvm.peripheral.Term", diskPath, 720, 480);
|
||||
EmulInstance portable = new EmulInstance(vm, "net.torvald.tsvm.peripheral.CharacterLCDdisplay", diskPath, 628, 302);
|
||||
|
||||
@@ -73,7 +73,7 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
|
||||
if (loaderInfo.display != null) {
|
||||
val loadedClass = Class.forName(loaderInfo.display)
|
||||
val loadedClassConstructor = loadedClass.getConstructor(String::class.java, vm::class.java)
|
||||
val loadedClassInstance = loadedClassConstructor.newInstance("./assets", vm)
|
||||
val loadedClassInstance = loadedClassConstructor.newInstance("./assets", vm, )
|
||||
gpu = (loadedClassInstance as GraphicsAdapter)
|
||||
|
||||
vm.getIO().blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, File(loaderInfo.diskPath)))
|
||||
|
||||
Reference in New Issue
Block a user