graphics: hardware scroll for pixels

This commit is contained in:
minjaesong
2021-09-21 21:48:16 +09:00
parent 5b56ab8fda
commit 883edaab3c
5 changed files with 54 additions and 8 deletions

View File

@@ -0,0 +1,4 @@
while (true) {
graphics.scrollFrame(1,1);
sys.spin();
}

View File

@@ -28,13 +28,13 @@ public class AppLoader {
appConfig.setWindowedMode(WIDTH, HEIGHT);
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, BasicRom.INSTANCE});
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{OEMBios.INSTANCE, BasicRom.INSTANCE});
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TandemBios.INSTANCE, BasicRom.INSTANCE});
//VM vm = new VM(128 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, WPBios.INSTANCE});
// VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, BasicRom.INSTANCE});
// VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{OEMBios.INSTANCE, BasicRom.INSTANCE});
VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TandemBios.INSTANCE, BasicRom.INSTANCE});
// VM vm = new VM(128 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, WPBios.INSTANCE});
// uncomment to target the TerranBASIC runner
VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TBASRelBios.INSTANCE});
// VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{TBASRelBios.INSTANCE});
EmulInstance reference = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceGraphicsAdapter", "assets/disk0");
EmulInstance reference2 = new EmulInstance(vm, "net.torvald.tsvm.peripheral.ReferenceLikeLCD", "assets/disk0");

View File

@@ -2,6 +2,7 @@ package net.torvald.tsvm
import net.torvald.UnsafeHelper
import net.torvald.tsvm.peripheral.GraphicsAdapter
import net.torvald.tsvm.peripheral.fmod
class GraphicsJSR223Delegate(val vm: VM) {
@@ -42,6 +43,23 @@ class GraphicsJSR223Delegate(val vm: VM) {
}
}
/**
* Sets absolute position of scrolling
*/
fun setFramebufferScroll(x: Int, y: Int) {
getFirstGPU()?.let {
it.framebufferScrollX = x
it.framebufferScrollY = y
}
}
fun scrollFrame(xdelta: Int, ydelta: Int) {
getFirstGPU()?.let {
it.framebufferScrollX = (it.framebufferScrollX + xdelta) fmod it.framebuffer.width
it.framebufferScrollY = (it.framebufferScrollY + ydelta) fmod it.framebuffer.height
}
}
fun getPixelDimension(): IntArray {
getFirstGPU()?.let { return intArrayOf(it.framebuffer.width, it.framebuffer.height) }
return intArrayOf(-1, -1)

View File

@@ -81,6 +81,8 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super
private var currentChrRom = 0
private var chrWidth = 7f
private var chrHeight = 14f
var framebufferScrollX = 0
var framebufferScrollY = 0
override var ttyFore: Int = TTY_FORE_DEFAULT // cannot be Byte
override var ttyBack: Int = TTY_BACK_DEFAULT // cannot be Byte
@@ -178,6 +180,10 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super
val adi = addr.toInt()
return when (addr) {
in 0 until 250880 -> framebuffer.pixels.get(adi)//framebuffer.getPixel(adi % WIDTH, adi / WIDTH).toByte()
250896L -> framebufferScrollX.toByte()
250897L -> framebufferScrollX.ushr(8).toByte()
250898L -> framebufferScrollY.toByte()
250899L -> framebufferScrollY.ushr(8).toByte()
in 250880 until 250972 -> unusedArea[adi - 250880]
in 250972 until 261632 -> spriteAndTextArea[addr - 250972]
in 261632 until 262144 -> peekPalette(adi - 261632)
@@ -201,6 +207,10 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super
unusedArea[adi - 250880] = byte
runCommand(byte)
}
250896L -> framebufferScrollX = framebufferScrollX.and(0xFFFFFF00.toInt()).or(bi)
250897L -> framebufferScrollX = framebufferScrollX.and(0xFFFF00FF.toInt()).or(bi shl 8)
250898L -> framebufferScrollY = framebufferScrollY.and(0xFFFFFF00.toInt()).or(bi)
250899L -> framebufferScrollY = framebufferScrollY.and(0xFFFF00FF.toInt()).or(bi shl 8)
in 250880 until 250972 -> unusedArea[adi - 250880] = byte
in 250972 until 261632 -> spriteAndTextArea[addr - 250972] = byte
in 261632 until 262144 -> pokePalette(adi - 261632, byte)
@@ -587,6 +597,9 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super
rendertex.dispose()
rendertex = Texture(framebuffer, Pixmap.Format.RGBA8888, false)
val texOffX = (framebufferScrollX fmod framebuffer.width) * -1f
val texOffY = (framebufferScrollY fmod framebuffer.height) * 1f
outFBOs[1].inUse {
outFBObatch.inUse {
outFBObatch.shader = null
@@ -625,7 +638,10 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super
paletteShader.setUniformf("lcdBaseCol", LCD_BASE_COL)
// draw framebuffer
outFBObatch.draw(rendertex, 0f, 0f)
outFBObatch.draw(rendertex, texOffX, texOffY)
outFBObatch.draw(rendertex, texOffX + framebuffer.width, texOffY)
outFBObatch.draw(rendertex, texOffX + framebuffer.width, texOffY - framebuffer.height)
outFBObatch.draw(rendertex, texOffX, texOffY - framebuffer.height)
// draw texts or sprites
@@ -1591,6 +1607,10 @@ void main() {
}
}
infix fun Int.fmod(other: Int): Int {
return Math.floorMod(this, other)
}
fun FrameBuffer.inUse(action: () -> Unit) {
this.begin()
action()

View File

@@ -156,10 +156,14 @@ From the start of the memory space:
command (writing to this memory address changes the status)
1: reset palette to default
2: fill framebuffer with given colour (arg1)
2 bytes
12 bytes
argument for "command" (arg1: Byte, arg2: Byte)
write to this address FIRST and then write to "command" to execute the command
76 bytes
2 bytes
framebuffer scroll X
2 bytes
framebuffer scroll Y
62 bytes
*Unused*
2988 bytes