mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-06 05:28:31 +09:00
tsvm: mouse coord fix
This commit is contained in:
@@ -3,6 +3,8 @@ package net.torvald.tsvm.peripheral
|
|||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.Input
|
import com.badlogic.gdx.Input
|
||||||
import com.badlogic.gdx.InputProcessor
|
import com.badlogic.gdx.InputProcessor
|
||||||
|
import com.badlogic.gdx.math.Vector2
|
||||||
|
import com.badlogic.gdx.utils.viewport.Viewport
|
||||||
import net.torvald.AddressOverflowException
|
import net.torvald.AddressOverflowException
|
||||||
import net.torvald.DanglingPointerException
|
import net.torvald.DanglingPointerException
|
||||||
import net.torvald.UnsafeHelper
|
import net.torvald.UnsafeHelper
|
||||||
@@ -18,10 +20,18 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
|||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Absolute x-position of the computer GUI */
|
/**
|
||||||
var guiPosX = 0
|
* Viewport that maps screen pixels (as reported by `Gdx.input.x/y`) to the VM's
|
||||||
/** Absolute y-position of the computer GUI */
|
* logical framebuffer coordinate space. The host application owns the rendering
|
||||||
var guiPosY = 0
|
* camera, so the host is responsible for installing a viewport whose world
|
||||||
|
* coordinates match the VM framebuffer (origin top-left, world size = framebuffer
|
||||||
|
* size in pixels) and whose screen rectangle matches where the VM is drawn.
|
||||||
|
*
|
||||||
|
* If left null, `Gdx.input.x/y` is forwarded verbatim — only correct when the VM
|
||||||
|
* occupies the entire window at 1:1 scale.
|
||||||
|
*/
|
||||||
|
var inputViewport: Viewport? = null
|
||||||
|
private val tmpMouseVec = Vector2()
|
||||||
|
|
||||||
/** Accepts a keycode */
|
/** Accepts a keycode */
|
||||||
private val keyboardBuffer = CircularArray<Byte>(32, true)
|
private val keyboardBuffer = CircularArray<Byte>(32, true)
|
||||||
@@ -296,9 +306,20 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
|||||||
keyEventBuffers.fill(0)
|
keyEventBuffers.fill(0)
|
||||||
|
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
// store mouse info
|
// store mouse info; unproject through the host-provided viewport so the
|
||||||
mouseX = (Gdx.input.x + guiPosX).toShort()
|
// VM sees logical framebuffer pixels regardless of window magnification,
|
||||||
mouseY = (Gdx.input.y + guiPosY).toShort()
|
// letterboxing or sub-region placement done by an embedding GDX app.
|
||||||
|
val vp = inputViewport
|
||||||
|
if (vp != null) {
|
||||||
|
tmpMouseVec.set(Gdx.input.x.toFloat(), Gdx.input.y.toFloat())
|
||||||
|
vp.unproject(tmpMouseVec)
|
||||||
|
mouseX = tmpMouseVec.x.toInt().toShort()
|
||||||
|
mouseY = tmpMouseVec.y.toInt().toShort()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mouseX = Gdx.input.x.toShort()
|
||||||
|
mouseY = Gdx.input.y.toShort()
|
||||||
|
}
|
||||||
mouseButtons = (if (Gdx.input.isButtonPressed(Input.Buttons.LEFT)) 1 else 0) or
|
mouseButtons = (if (Gdx.input.isButtonPressed(Input.Buttons.LEFT)) 1 else 0) or
|
||||||
(if (Gdx.input.isButtonPressed(Input.Buttons.RIGHT)) 2 else 0)
|
(if (Gdx.input.isButtonPressed(Input.Buttons.RIGHT)) 2 else 0)
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
|
import com.badlogic.gdx.utils.viewport.StretchViewport
|
||||||
|
import com.badlogic.gdx.utils.viewport.Viewport
|
||||||
import net.torvald.terrarum.DefaultGL32Shaders
|
import net.torvald.terrarum.DefaultGL32Shaders
|
||||||
import net.torvald.tsvm.peripheral.*
|
import net.torvald.tsvm.peripheral.*
|
||||||
import net.torvald.tsvm.peripheral.GraphicsAdapter.Companion.DRAW_SHADER_VERT
|
import net.torvald.tsvm.peripheral.GraphicsAdapter.Companion.DRAW_SHADER_VERT
|
||||||
@@ -48,6 +50,14 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
|
|||||||
lateinit var batch: SpriteBatch
|
lateinit var batch: SpriteBatch
|
||||||
lateinit var camera: OrthographicCamera
|
lateinit var camera: OrthographicCamera
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps window pixels to the VM framebuffer (origin top-left, world size =
|
||||||
|
* viewportWidth × viewportHeight). Stretches to fill the whole window so it
|
||||||
|
* matches the `MAGN`-scaled blit at the end of [renderGame]. Handed to
|
||||||
|
* [IOSpace.inputViewport] so mouse coordinates unproject correctly.
|
||||||
|
*/
|
||||||
|
lateinit var inputViewport: Viewport
|
||||||
|
|
||||||
var gpu: GraphicsAdapter? = null
|
var gpu: GraphicsAdapter? = null
|
||||||
lateinit var vmRunner: VMRunner
|
lateinit var vmRunner: VMRunner
|
||||||
lateinit var coroutineJob: Thread
|
lateinit var coroutineJob: Thread
|
||||||
@@ -103,9 +113,20 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
|
|||||||
gpuFBO = FrameBuffer(Pixmap.Format.RGBA8888, viewportWidth, viewportHeight, false)
|
gpuFBO = FrameBuffer(Pixmap.Format.RGBA8888, viewportWidth, viewportHeight, false)
|
||||||
winFBO = FrameBuffer(Pixmap.Format.RGBA8888, viewportWidth, viewportHeight, false)
|
winFBO = FrameBuffer(Pixmap.Format.RGBA8888, viewportWidth, viewportHeight, false)
|
||||||
|
|
||||||
|
val inputCam = OrthographicCamera().also {
|
||||||
|
it.setToOrtho(true, viewportWidth.toFloat(), viewportHeight.toFloat())
|
||||||
|
}
|
||||||
|
inputViewport = StretchViewport(viewportWidth.toFloat(), viewportHeight.toFloat(), inputCam)
|
||||||
|
inputViewport.update(Gdx.graphics.width, Gdx.graphics.height, true)
|
||||||
|
|
||||||
init()
|
init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun resize(width: Int, height: Int) {
|
||||||
|
super.resize(width, height)
|
||||||
|
inputViewport.update(width, height, true)
|
||||||
|
}
|
||||||
|
|
||||||
private fun init() {
|
private fun init() {
|
||||||
vm.init()
|
vm.init()
|
||||||
|
|
||||||
@@ -148,6 +169,7 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
|
|||||||
}
|
}
|
||||||
|
|
||||||
Gdx.input.inputProcessor = vm.getIO()
|
Gdx.input.inputProcessor = vm.getIO()
|
||||||
|
vm.getIO().inputViewport = inputViewport
|
||||||
|
|
||||||
if (usememvwr) memvwr = Memvwr(vm)
|
if (usememvwr) memvwr = Memvwr(vm)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user