From cc41218d375424e31fd411601fc9ac46fc84c6b4 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 3 Jul 2022 00:41:04 +0200 Subject: [PATCH] added nicer vm example --- compiler/res/prog8lib/virtual/syslib.p8 | 9 +++ examples/test.p8 | 21 +------ examples/vm/bouncegfx.p8 | 59 +++++++++++++++++++ examples/vm/pixelshader.p8 | 28 +++++++++ virtualmachine/src/prog8/vm/GraphicsWindow.kt | 8 +++ virtualmachine/src/prog8/vm/SysCalls.kt | 5 +- virtualmachine/src/prog8/vm/VirtualMachine.kt | 10 ++++ 7 files changed, 119 insertions(+), 21 deletions(-) create mode 100644 examples/vm/bouncegfx.p8 create mode 100644 examples/vm/pixelshader.p8 diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index 68803cc36..fa6600ed4 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -95,6 +95,15 @@ sys { syscall 10 }} } + + sub gfx_getpixel(uword xx, uword yy) -> ubyte { + %asm {{ + loadm.w r0, {sys.gfx_getpixel.xx} + loadm.w r1, {sys.gfx_getpixel.yy} + syscall 30 + return + }} + } } cx16 { diff --git a/examples/test.p8 b/examples/test.p8 index df9147634..a98bc198f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,28 +1,9 @@ %import textio %zeropage basicsafe -; NOTE: meant to test to virtual machine output target (use -target virtual) - main { sub start() { - - ; a "pixelshader": - sys.gfx_enable(0) ; enable lo res screen - ubyte shifter - - repeat { - uword xx - uword yy = 0 - repeat 240 { - xx = 0 - repeat 320 { - sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) - xx++ - } - yy++ - } - shifter+=4 - } + txt.print("hello!\n") } } diff --git a/examples/vm/bouncegfx.p8 b/examples/vm/bouncegfx.p8 new file mode 100644 index 000000000..1f475f867 --- /dev/null +++ b/examples/vm/bouncegfx.p8 @@ -0,0 +1,59 @@ +%import textio +%zeropage basicsafe + +; NOTE: meant to test to virtual machine output target (use -target virtual) + +main { + + sub start() { + word[128] particleX + word[128] particleY + byte[128] particleDX + byte[128] particleDY + + ubyte pi + for pi in 0 to 127 { + particleX[pi] = rndw() % 319 as word + particleY[pi] = rndw() % 240 as word + particleDX[pi] = (rnd() & 1)*2 as byte - 1 + particleDY[pi] = (rnd() & 1)*2 as byte - 1 + } + + sys.gfx_enable(0) ; enable lo res screen + + repeat { + fade() + plot_particles() + sys.waitvsync() + } + + sub fade() { + uword xx + uword yy + for yy in 0 to 239 { + for xx in 0 to 319 { + ubyte pixel = sys.gfx_getpixel(xx, yy) + if pixel>4 + pixel-=4 + sys.gfx_plot(xx, yy, pixel) + } + } + } + + sub plot_particles() { + for pi in 0 to 127 { + particleX[pi] += particleDX[pi] + particleY[pi] += particleDY[pi] + if particleX[pi]<0 or particleX[pi]>319 { + particleDX[pi] *= -1 + particleX[pi] += particleDX[pi] * 2 + } + if particleY[pi]<0 or particleY[pi]>239 { + particleDY[pi] *= -1 + particleY[pi] += particleDY[pi] * 2 + } + sys.gfx_plot(particleX[pi] as uword, particleY[pi] as uword, 255) + } + } + } +} diff --git a/examples/vm/pixelshader.p8 b/examples/vm/pixelshader.p8 new file mode 100644 index 000000000..df9147634 --- /dev/null +++ b/examples/vm/pixelshader.p8 @@ -0,0 +1,28 @@ +%import textio +%zeropage basicsafe + +; NOTE: meant to test to virtual machine output target (use -target virtual) + +main { + + sub start() { + + ; a "pixelshader": + sys.gfx_enable(0) ; enable lo res screen + ubyte shifter + + repeat { + uword xx + uword yy = 0 + repeat 240 { + xx = 0 + repeat 320 { + sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) + xx++ + } + yy++ + } + shifter+=4 + } + } +} diff --git a/virtualmachine/src/prog8/vm/GraphicsWindow.kt b/virtualmachine/src/prog8/vm/GraphicsWindow.kt index d81830170..1710680d4 100644 --- a/virtualmachine/src/prog8/vm/GraphicsWindow.kt +++ b/virtualmachine/src/prog8/vm/GraphicsWindow.kt @@ -65,6 +65,14 @@ class GraphicsWindow(val pixelWidth: Int, val pixelHeight: Int, val pixelScaling throw IllegalArgumentException("plot y outside of screen: $y") image.setRGB(x, y, Color(color, color, color, 255).rgb) } + + fun getpixel(x: Int, y: Int): Int { + if(x<0 || x>=pixelWidth) + throw IllegalArgumentException("plot x outside of screen: $x") + if(y<0 || y>=pixelHeight) + throw IllegalArgumentException("plot y outside of screen: $y") + return image.getRGB(x, y) + } } diff --git a/virtualmachine/src/prog8/vm/SysCalls.kt b/virtualmachine/src/prog8/vm/SysCalls.kt index 2f89091fe..39d1db9b9 100644 --- a/virtualmachine/src/prog8/vm/SysCalls.kt +++ b/virtualmachine/src/prog8/vm/SysCalls.kt @@ -35,6 +35,7 @@ SYSCALLS: 27 = reverse_words array 28 = reverse_floats array 29 = compare strings +30 = gfx_getpixel ; get byte pixel value at coordinates r0.w/r1.w */ enum class Syscall { @@ -67,7 +68,8 @@ enum class Syscall { REVERSE_BYTES, REVERSE_WORDS, REVERSE_FLOATS, - COMPARE_STRINGS + COMPARE_STRINGS, + GFX_GETPIXEL } object SysCalls { @@ -114,6 +116,7 @@ object SysCalls { Syscall.GFX_ENABLE -> vm.gfx_enable() Syscall.GFX_CLEAR -> vm.gfx_clear() Syscall.GFX_PLOT -> vm.gfx_plot() + Syscall.GFX_GETPIXEL ->vm.gfx_getpixel() Syscall.WAIT -> { val millis = vm.registers.getUW(0).toLong() * 1000/60 Thread.sleep(millis) diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index 7244c26f5..a3e4a365e 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -1,6 +1,7 @@ package prog8.vm import prog8.code.target.virtual.IVirtualMachineRunner +import java.awt.Color import java.awt.Toolkit import java.util.* import kotlin.math.* @@ -1799,6 +1800,15 @@ class VirtualMachine(val memory: Memory, program: List) { window?.plot(registers.getUW(0).toInt(), registers.getUW(1).toInt(), registers.getUB(2).toInt()) } + fun gfx_getpixel() { + if(window==null) + registers.setUB(0, 0u) + else { + val color = Color(window!!.getpixel(registers.getUW(0).toInt(), registers.getUW(1).toInt())) + registers.setUB(0, color.green.toUByte()) + } + } + fun gfx_close() { window?.close() }