mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
rendering: outsource input handling
This commit is contained in:
parent
710e045e90
commit
64b2d2eeb8
@ -99,7 +99,7 @@ class Camera(
|
|||||||
var yOffset = yPos - this.lastMouseY
|
var yOffset = yPos - this.lastMouseY
|
||||||
lastMouseX = xPos
|
lastMouseX = xPos
|
||||||
lastMouseY = yPos
|
lastMouseY = yPos
|
||||||
if (renderWindow.currentKeyConsumer != null) {
|
if (renderWindow.inputHandler.currentKeyConsumer != null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
xOffset *= mouseSensitivity
|
xOffset *= mouseSensitivity
|
||||||
@ -123,31 +123,31 @@ class Camera(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun init(renderWindow: RenderWindow) {
|
fun init(renderWindow: RenderWindow) {
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_FORWARD) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_FORWARD) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyForwardDown = keyAction == KeyAction.PRESS
|
keyForwardDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_LEFT) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_LEFT) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyLeftDown = keyAction == KeyAction.PRESS
|
keyLeftDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_BACKWARDS) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_BACKWARDS) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyBackDown = keyAction == KeyAction.PRESS
|
keyBackDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_RIGHT) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_RIGHT) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyRightDown = keyAction == KeyAction.PRESS
|
keyRightDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_FLY_UP) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_FLY_UP) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyFlyUp = keyAction == KeyAction.PRESS
|
keyFlyUp = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_FLY_DOWN) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_FLY_DOWN) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyFlyDown = keyAction == KeyAction.PRESS
|
keyFlyDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_SPRINT) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_SPRINT) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keySprintDown = keyAction == KeyAction.PRESS
|
keySprintDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.ZOOM) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.ZOOM) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyZoomDown = keyAction == KeyAction.PRESS
|
keyZoomDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.MOVE_JUMP) { _: KeyCodes, keyAction: KeyAction ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.MOVE_JUMP) { _: KeyCodes, keyAction: KeyAction ->
|
||||||
keyJumpDown = keyAction == KeyAction.PRESS
|
keyJumpDown = keyAction == KeyAction.PRESS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ class Camera(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun handleInput(deltaTime: Double) {
|
fun handleInput(deltaTime: Double) {
|
||||||
if (renderWindow.currentKeyConsumer != null) { // ToDo
|
if (renderWindow.inputHandler.currentKeyConsumer != null) { // ToDo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var cameraSpeed = movementSpeed * deltaTime
|
var cameraSpeed = movementSpeed * deltaTime
|
||||||
|
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.input.key
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.Minosoft
|
||||||
|
import de.bixilon.minosoft.config.StaticConfiguration
|
||||||
|
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||||
|
import de.bixilon.minosoft.config.key.KeyAction
|
||||||
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.input.camera.Camera
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.input.KeyConsumer
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
|
import org.lwjgl.glfw.GLFW
|
||||||
|
|
||||||
|
class RenderWindowInputHandler(
|
||||||
|
val renderWindow: RenderWindow,
|
||||||
|
) {
|
||||||
|
val connection: PlayConnection = renderWindow.connection
|
||||||
|
|
||||||
|
private val keyBindingCallbacks: MutableMap<ResourceLocation, Pair<KeyBinding, MutableSet<((keyCode: KeyCodes, keyEvent: KeyAction) -> Unit)>>> = mutableMapOf()
|
||||||
|
private val keysDown: MutableSet<KeyCodes> = mutableSetOf()
|
||||||
|
private val keyBindingDown: MutableSet<KeyBinding> = mutableSetOf()
|
||||||
|
val camera: Camera = Camera(connection, Minosoft.getConfig().config.game.camera.fov, renderWindow)
|
||||||
|
|
||||||
|
private var skipNextCharPress = false
|
||||||
|
|
||||||
|
private var _currentInputConsumer: KeyConsumer? = null
|
||||||
|
var mouseCatch = !StaticConfiguration.DEBUG_MODE
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH) { _: KeyCodes, _: KeyAction ->
|
||||||
|
mouseCatch = !mouseCatch
|
||||||
|
if (mouseCatch) {
|
||||||
|
GLFW.glfwSetInputMode(renderWindow.windowId, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED)
|
||||||
|
} else {
|
||||||
|
GLFW.glfwSetInputMode(renderWindow.windowId, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL)
|
||||||
|
}
|
||||||
|
renderWindow.sendDebugMessage("Toggled mouse catch!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentKeyConsumer: KeyConsumer?
|
||||||
|
get() = _currentInputConsumer
|
||||||
|
set(value) {
|
||||||
|
_currentInputConsumer = value
|
||||||
|
for ((_, binding) in keyBindingCallbacks) {
|
||||||
|
if (!keyBindingDown.contains(binding.first)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!binding.first.action.containsKey(KeyAction.TOGGLE) && !binding.first.action.containsKey(KeyAction.CHANGE)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for (keyCallback in binding.second) {
|
||||||
|
keyCallback.invoke(KeyCodes.KEY_UNKNOWN, KeyAction.RELEASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ToDo: move to mouse consumer
|
||||||
|
if (value == null) {
|
||||||
|
if (mouseCatch) {
|
||||||
|
renderWindow.renderQueue.add { GLFW.glfwSetInputMode(renderWindow.windowId, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
renderWindow.renderQueue.add { GLFW.glfwSetInputMode(renderWindow.windowId, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL) }
|
||||||
|
}
|
||||||
|
keyBindingDown.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun invoke(window: Long, key: Int, scancode: Int, action: Int, mods: Int) {
|
||||||
|
val keyCode = KeyCodes.KEY_CODE_GLFW_ID_MAP[key] ?: KeyCodes.KEY_UNKNOWN
|
||||||
|
val keyAction = when (action) {
|
||||||
|
GLFW.GLFW_PRESS -> KeyAction.PRESS
|
||||||
|
GLFW.GLFW_RELEASE -> KeyAction.RELEASE
|
||||||
|
// ToDo: Double, Hold
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
if (keyAction == KeyAction.PRESS) {
|
||||||
|
keysDown.add(keyCode)
|
||||||
|
} else if (keyAction == KeyAction.RELEASE) {
|
||||||
|
keysDown.remove(keyCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyAction == KeyAction.PRESS) {
|
||||||
|
// ToDo: Repeatable keys, long holding, etc
|
||||||
|
currentKeyConsumer?.keyInput(keyCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
val previousKeyConsumer = currentKeyConsumer
|
||||||
|
for ((_, keyCallbackPair) in keyBindingCallbacks) {
|
||||||
|
run {
|
||||||
|
val keyBinding = keyCallbackPair.first
|
||||||
|
val keyCallbacks = keyCallbackPair.second
|
||||||
|
|
||||||
|
var anyCheckRun = false
|
||||||
|
|
||||||
|
keyBinding.action[KeyAction.MODIFIER]?.let {
|
||||||
|
val previousKeysDown = if (keyAction == KeyAction.RELEASE) {
|
||||||
|
val previousKeysDown = keysDown.toMutableList()
|
||||||
|
previousKeysDown.add(keyCode)
|
||||||
|
previousKeysDown
|
||||||
|
} else {
|
||||||
|
keysDown
|
||||||
|
}
|
||||||
|
if (!previousKeysDown.containsAll(it)) {
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
anyCheckRun = true
|
||||||
|
}
|
||||||
|
keyBinding.action[KeyAction.CHANGE]?.let {
|
||||||
|
if (!it.contains(keyCode)) {
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
anyCheckRun = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// release or press
|
||||||
|
if (keyBinding.action[KeyAction.CHANGE] == null) {
|
||||||
|
keyBinding.action[keyAction].let {
|
||||||
|
if (it == null) {
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
if (!it.contains(keyCode)) {
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
anyCheckRun = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!anyCheckRun) {
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyAction == KeyAction.PRESS) {
|
||||||
|
keyBindingDown.add(keyBinding)
|
||||||
|
} else if (keyAction == KeyAction.RELEASE) {
|
||||||
|
keyBindingDown.remove(keyBinding)
|
||||||
|
}
|
||||||
|
for (keyCallback in keyCallbacks) {
|
||||||
|
keyCallback.invoke(keyCode, keyAction)
|
||||||
|
if (previousKeyConsumer != currentKeyConsumer) {
|
||||||
|
skipNextCharPress = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun invoke(window: Long, char: Int) {
|
||||||
|
if (skipNextCharPress) {
|
||||||
|
skipNextCharPress = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentKeyConsumer?.charInput(char.toChar())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun invoke(window: Long, xPos: Double, yPos: Double) {
|
||||||
|
camera.mouseCallback(xPos, yPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerKeyCallback(resourceLocation: ResourceLocation, ignoreConsumer: Boolean = false, callback: ((keyCode: KeyCodes, keyEvent: KeyAction) -> Unit)) {
|
||||||
|
var resourceLocationCallbacks = keyBindingCallbacks[resourceLocation]?.second
|
||||||
|
if (resourceLocationCallbacks == null) {
|
||||||
|
resourceLocationCallbacks = mutableSetOf()
|
||||||
|
val keyBinding = Minosoft.getConfig().config.game.controls.keyBindings.entries[resourceLocation] ?: return
|
||||||
|
keyBindingCallbacks[resourceLocation] = Pair(keyBinding, resourceLocationCallbacks)
|
||||||
|
}
|
||||||
|
resourceLocationCallbacks.add { keyCode, keyEvent ->
|
||||||
|
if (!ignoreConsumer) {
|
||||||
|
if (currentKeyConsumer != null) {
|
||||||
|
return@add
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.invoke(keyCode, keyEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterKeyBinding(it: ResourceLocation) {
|
||||||
|
keyBindingCallbacks.remove(it)
|
||||||
|
}
|
||||||
|
}
|
@ -13,23 +13,19 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering
|
package de.bixilon.minosoft.gui.rendering
|
||||||
|
|
||||||
import de.bixilon.minosoft.Minosoft
|
|
||||||
import de.bixilon.minosoft.config.StaticConfiguration
|
|
||||||
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||||
import de.bixilon.minosoft.config.key.KeyAction
|
import de.bixilon.minosoft.config.key.KeyAction
|
||||||
import de.bixilon.minosoft.config.key.KeyBinding
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
import de.bixilon.minosoft.data.text.RGBColor
|
import de.bixilon.minosoft.data.text.RGBColor
|
||||||
import de.bixilon.minosoft.gui.input.camera.Camera
|
|
||||||
import de.bixilon.minosoft.gui.input.camera.FrustumChangeCallback
|
import de.bixilon.minosoft.gui.input.camera.FrustumChangeCallback
|
||||||
|
import de.bixilon.minosoft.gui.input.key.RenderWindowInputHandler
|
||||||
import de.bixilon.minosoft.gui.modding.events.RenderingStateChangeEvent
|
import de.bixilon.minosoft.gui.modding.events.RenderingStateChangeEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.font.Font
|
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike
|
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLikeTexture
|
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLikeTexture
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.input.KeyConsumer
|
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder
|
import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||||
@ -57,26 +53,22 @@ class RenderWindow(
|
|||||||
val connection: PlayConnection,
|
val connection: PlayConnection,
|
||||||
val rendering: Rendering,
|
val rendering: Rendering,
|
||||||
) {
|
) {
|
||||||
private val keyBindingCallbacks: MutableMap<ResourceLocation, Pair<KeyBinding, MutableSet<((keyCode: KeyCodes, keyEvent: KeyAction) -> Unit)>>> = mutableMapOf()
|
|
||||||
private val keysDown: MutableSet<KeyCodes> = mutableSetOf()
|
|
||||||
private val keyBindingDown: MutableSet<KeyBinding> = mutableSetOf()
|
|
||||||
val renderStats = RenderStats()
|
val renderStats = RenderStats()
|
||||||
var screenDimensions = Vec2i(900, 500)
|
var screenDimensions = Vec2i(900, 500)
|
||||||
private set
|
private set
|
||||||
var screenDimensionsF = Vec2(screenDimensions)
|
var screenDimensionsF = Vec2(screenDimensions)
|
||||||
private set
|
private set
|
||||||
|
val inputHandler = RenderWindowInputHandler(this)
|
||||||
|
|
||||||
private var windowId = 0L
|
var windowId = 0L
|
||||||
private var deltaFrameTime = 0.0 // time between current frame and last frame
|
private var deltaFrameTime = 0.0 // time between current frame and last frame
|
||||||
|
|
||||||
private var lastFrame = 0.0
|
private var lastFrame = 0.0
|
||||||
val camera: Camera = Camera(connection, Minosoft.getConfig().config.game.camera.fov, this)
|
|
||||||
private val latch = CountUpAndDownLatch(1)
|
private val latch = CountUpAndDownLatch(1)
|
||||||
|
|
||||||
private var renderingState = RenderingStates.RUNNING
|
private var renderingState = RenderingStates.RUNNING
|
||||||
|
|
||||||
private var polygonEnabled = false
|
private var polygonEnabled = false
|
||||||
private var mouseCatch = !StaticConfiguration.DEBUG_MODE
|
|
||||||
|
|
||||||
private val screenshotTaker = ScreenshotTaker(this)
|
private val screenshotTaker = ScreenshotTaker(this)
|
||||||
val tintColorCalculator = TintColorCalculator(connection.world)
|
val tintColorCalculator = TintColorCalculator(connection.world)
|
||||||
@ -87,45 +79,14 @@ class RenderWindow(
|
|||||||
|
|
||||||
val renderQueue = ConcurrentLinkedQueue<Runnable>()
|
val renderQueue = ConcurrentLinkedQueue<Runnable>()
|
||||||
|
|
||||||
private var _currentInputConsumer: KeyConsumer? = null
|
|
||||||
|
|
||||||
private var skipNextCharPress = false
|
|
||||||
|
|
||||||
lateinit var WHITE_TEXTURE: TextureLike
|
lateinit var WHITE_TEXTURE: TextureLike
|
||||||
|
|
||||||
|
|
||||||
val screenResizeCallbacks: MutableSet<ScreenResizeCallback> = mutableSetOf(camera)
|
val screenResizeCallbacks: MutableSet<ScreenResizeCallback> = mutableSetOf(inputHandler.camera)
|
||||||
|
|
||||||
var tickCount = 0L
|
var tickCount = 0L
|
||||||
var lastTickTimer = System.currentTimeMillis()
|
var lastTickTimer = System.currentTimeMillis()
|
||||||
|
|
||||||
var currentKeyConsumer: KeyConsumer?
|
|
||||||
get() = _currentInputConsumer
|
|
||||||
set(value) {
|
|
||||||
_currentInputConsumer = value
|
|
||||||
for ((_, binding) in keyBindingCallbacks) {
|
|
||||||
if (!keyBindingDown.contains(binding.first)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (!binding.first.action.containsKey(KeyAction.TOGGLE) && !binding.first.action.containsKey(KeyAction.CHANGE)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for (keyCallback in binding.second) {
|
|
||||||
keyCallback.invoke(KeyCodes.KEY_UNKNOWN, KeyAction.RELEASE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ToDo: move to mouse consumer
|
|
||||||
if (value == null) {
|
|
||||||
if (mouseCatch) {
|
|
||||||
renderQueue.add { glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED) }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
renderQueue.add { glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_NORMAL) }
|
|
||||||
}
|
|
||||||
keyBindingDown.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ConnectionStateChangeEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<ConnectionStateChangeEvent> {
|
||||||
if (it.connection.isDisconnected) {
|
if (it.connection.isDisconnected) {
|
||||||
@ -143,8 +104,8 @@ class RenderWindow(
|
|||||||
latch.countDown()
|
latch.countDown()
|
||||||
}
|
}
|
||||||
renderQueue.add {
|
renderQueue.add {
|
||||||
camera.setPosition(packet.position)
|
inputHandler.camera.setPosition(packet.position)
|
||||||
camera.setRotation(packet.rotation.yaw, packet.rotation.pitch)
|
inputHandler.camera.setRotation(packet.rotation.yaw, packet.rotation.pitch)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -174,102 +135,20 @@ class RenderWindow(
|
|||||||
glfwTerminate()
|
glfwTerminate()
|
||||||
throw RuntimeException("Failed to create the GLFW window")
|
throw RuntimeException("Failed to create the GLFW window")
|
||||||
}
|
}
|
||||||
camera.init(this)
|
inputHandler.camera.init(this)
|
||||||
|
|
||||||
tintColorCalculator.init(connection.assetsManager)
|
tintColorCalculator.init(connection.assetsManager)
|
||||||
|
|
||||||
|
|
||||||
glfwSetKeyCallback(this.windowId) { _: Long, key: Int, _: Int, action: Int, _: Int ->
|
glfwSetKeyCallback(this.windowId, inputHandler::invoke)
|
||||||
val keyCode = KeyCodes.KEY_CODE_GLFW_ID_MAP[key] ?: KeyCodes.KEY_UNKNOWN
|
|
||||||
val keyAction = when (action) {
|
|
||||||
GLFW_PRESS -> KeyAction.PRESS
|
|
||||||
GLFW_RELEASE -> KeyAction.RELEASE
|
|
||||||
// ToDo: Double, Hold
|
|
||||||
else -> return@glfwSetKeyCallback
|
|
||||||
}
|
|
||||||
if (keyAction == KeyAction.PRESS) {
|
|
||||||
keysDown.add(keyCode)
|
|
||||||
} else if (keyAction == KeyAction.RELEASE) {
|
|
||||||
keysDown.remove(keyCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyAction == KeyAction.PRESS) {
|
glfwSetCharCallback(windowId, inputHandler::invoke)
|
||||||
// ToDo: Repeatable keys, long holding, etc
|
|
||||||
currentKeyConsumer?.keyInput(keyCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
val previousKeyConsumer = currentKeyConsumer
|
if (inputHandler.mouseCatch) {
|
||||||
for ((_, keyCallbackPair) in keyBindingCallbacks) {
|
|
||||||
run {
|
|
||||||
val keyBinding = keyCallbackPair.first
|
|
||||||
val keyCallbacks = keyCallbackPair.second
|
|
||||||
|
|
||||||
var anyCheckRun = false
|
|
||||||
|
|
||||||
keyBinding.action[KeyAction.MODIFIER]?.let {
|
|
||||||
val previousKeysDown = if (keyAction == KeyAction.RELEASE) {
|
|
||||||
val previousKeysDown = keysDown.toMutableList()
|
|
||||||
previousKeysDown.add(keyCode)
|
|
||||||
previousKeysDown
|
|
||||||
} else {
|
|
||||||
keysDown
|
|
||||||
}
|
|
||||||
if (!previousKeysDown.containsAll(it)) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
anyCheckRun = true
|
|
||||||
}
|
|
||||||
keyBinding.action[KeyAction.CHANGE]?.let {
|
|
||||||
if (!it.contains(keyCode)) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
anyCheckRun = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// release or press
|
|
||||||
if (keyBinding.action[KeyAction.CHANGE] == null) {
|
|
||||||
keyBinding.action[keyAction].let {
|
|
||||||
if (it == null) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
if (!it.contains(keyCode)) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
anyCheckRun = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!anyCheckRun) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyAction == KeyAction.PRESS) {
|
|
||||||
keyBindingDown.add(keyBinding)
|
|
||||||
} else if (keyAction == KeyAction.RELEASE) {
|
|
||||||
keyBindingDown.remove(keyBinding)
|
|
||||||
}
|
|
||||||
for (keyCallback in keyCallbacks) {
|
|
||||||
keyCallback.invoke(keyCode, keyAction)
|
|
||||||
if (previousKeyConsumer != currentKeyConsumer) {
|
|
||||||
skipNextCharPress = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwSetCharCallback(windowId) { _: Long, char: Int ->
|
|
||||||
if (skipNextCharPress) {
|
|
||||||
skipNextCharPress = false
|
|
||||||
return@glfwSetCharCallback
|
|
||||||
}
|
|
||||||
currentKeyConsumer?.charInput(char.toChar())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouseCatch) {
|
|
||||||
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
|
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
|
||||||
}
|
}
|
||||||
glfwSetCursorPosCallback(windowId) { _: Long, xPos: Double, yPos: Double -> camera.mouseCallback(xPos, yPos) }
|
glfwSetCursorPosCallback(windowId, inputHandler::invoke)
|
||||||
|
|
||||||
MemoryStack.stackPush().let { stack ->
|
MemoryStack.stackPush().let { stack ->
|
||||||
val pWidth = stack.mallocInt(1)
|
val pWidth = stack.mallocInt(1)
|
||||||
val pHeight = stack.mallocInt(1)
|
val pHeight = stack.mallocInt(1)
|
||||||
@ -328,7 +207,7 @@ class RenderWindow(
|
|||||||
for (renderer in rendererMap.values) {
|
for (renderer in rendererMap.values) {
|
||||||
renderer.postInit()
|
renderer.postInit()
|
||||||
if (renderer is ShaderHolder) {
|
if (renderer is ShaderHolder) {
|
||||||
camera.addShaders(renderer.shader)
|
inputHandler.camera.addShaders(renderer.shader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +261,7 @@ class RenderWindow(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerGlobalKeyCombinations() {
|
private fun registerGlobalKeyCombinations() {
|
||||||
registerKeyCallback(KeyBindingsNames.DEBUG_POLYGON) { _: KeyCodes, _: KeyAction ->
|
inputHandler.registerKeyCallback(KeyBindingsNames.DEBUG_POLYGON) { _: KeyCodes, _: KeyAction ->
|
||||||
polygonEnabled = !polygonEnabled
|
polygonEnabled = !polygonEnabled
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, if (polygonEnabled) {
|
glPolygonMode(GL_FRONT_AND_BACK, if (polygonEnabled) {
|
||||||
GL_LINE
|
GL_LINE
|
||||||
@ -391,19 +270,10 @@ class RenderWindow(
|
|||||||
})
|
})
|
||||||
sendDebugMessage("Toggled polygon mode!")
|
sendDebugMessage("Toggled polygon mode!")
|
||||||
}
|
}
|
||||||
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH) { _: KeyCodes, _: KeyAction ->
|
inputHandler.registerKeyCallback(KeyBindingsNames.QUIT_RENDERING) { _: KeyCodes, _: KeyAction ->
|
||||||
mouseCatch = !mouseCatch
|
|
||||||
if (mouseCatch) {
|
|
||||||
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
|
|
||||||
} else {
|
|
||||||
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_NORMAL)
|
|
||||||
}
|
|
||||||
sendDebugMessage("Toggled mouse catch!")
|
|
||||||
}
|
|
||||||
registerKeyCallback(KeyBindingsNames.QUIT_RENDERING) { _: KeyCodes, _: KeyAction ->
|
|
||||||
glfwSetWindowShouldClose(windowId, true)
|
glfwSetWindowShouldClose(windowId, true)
|
||||||
}
|
}
|
||||||
registerKeyCallback(KeyBindingsNames.TAKE_SCREENSHOT, true) { _: KeyCodes, _: KeyAction ->
|
inputHandler.registerKeyCallback(KeyBindingsNames.TAKE_SCREENSHOT, true) { _: KeyCodes, _: KeyAction ->
|
||||||
screenshotTaker.takeScreenshot()
|
screenshotTaker.takeScreenshot()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,7 +292,7 @@ class RenderWindow(
|
|||||||
val currentTickTime = System.currentTimeMillis()
|
val currentTickTime = System.currentTimeMillis()
|
||||||
if (currentTickTime - this.lastTickTimer > ProtocolDefinition.TICK_TIME) {
|
if (currentTickTime - this.lastTickTimer > ProtocolDefinition.TICK_TIME) {
|
||||||
tickCount++
|
tickCount++
|
||||||
currentKeyConsumer?.tick(tickCount)
|
inputHandler.currentKeyConsumer?.tick(tickCount)
|
||||||
this.lastTickTimer = currentTickTime
|
this.lastTickTimer = currentTickTime
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,8 +313,8 @@ class RenderWindow(
|
|||||||
|
|
||||||
glfwSwapBuffers(windowId)
|
glfwSwapBuffers(windowId)
|
||||||
glfwPollEvents()
|
glfwPollEvents()
|
||||||
camera.draw()
|
inputHandler.camera.draw()
|
||||||
camera.handleInput(deltaFrameTime)
|
inputHandler.camera.handleInput(deltaFrameTime)
|
||||||
|
|
||||||
// handle opengl context tasks, but limit it per frame
|
// handle opengl context tasks, but limit it per frame
|
||||||
var actionsDone = 0
|
var actionsDone = 0
|
||||||
@ -496,23 +366,6 @@ class RenderWindow(
|
|||||||
connection.fireEvent(RenderingStateChangeEvent(connection, previousState, renderingState))
|
connection.fireEvent(RenderingStateChangeEvent(connection, previousState, renderingState))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerKeyCallback(resourceLocation: ResourceLocation, ignoreConsumer: Boolean = false, callback: ((keyCode: KeyCodes, keyEvent: KeyAction) -> Unit)) {
|
|
||||||
var resourceLocationCallbacks = keyBindingCallbacks[resourceLocation]?.second
|
|
||||||
if (resourceLocationCallbacks == null) {
|
|
||||||
resourceLocationCallbacks = mutableSetOf()
|
|
||||||
val keyBinding = Minosoft.getConfig().config.game.controls.keyBindings.entries[resourceLocation] ?: return
|
|
||||||
keyBindingCallbacks[resourceLocation] = Pair(keyBinding, resourceLocationCallbacks)
|
|
||||||
}
|
|
||||||
resourceLocationCallbacks.add { keyCode, keyEvent ->
|
|
||||||
if (!ignoreConsumer) {
|
|
||||||
if (currentKeyConsumer != null) {
|
|
||||||
return@add
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback.invoke(keyCode, keyEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun registerRenderer(renderBuilder: RenderBuilder) {
|
fun registerRenderer(renderBuilder: RenderBuilder) {
|
||||||
val renderer = renderBuilder.build(connection, this)
|
val renderer = renderBuilder.build(connection, this)
|
||||||
rendererMap[renderBuilder.RESOURCE_LOCATION] = renderer
|
rendererMap[renderBuilder.RESOURCE_LOCATION] = renderer
|
||||||
@ -520,7 +373,7 @@ class RenderWindow(
|
|||||||
screenResizeCallbacks.add(renderer)
|
screenResizeCallbacks.add(renderer)
|
||||||
}
|
}
|
||||||
if (renderer is FrustumChangeCallback) {
|
if (renderer is FrustumChangeCallback) {
|
||||||
camera.addFrustumChangeCallback(renderer)
|
inputHandler.camera.addFrustumChangeCallback(renderer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,8 +384,4 @@ class RenderWindow(
|
|||||||
fun sendDebugMessage(message: String) {
|
fun sendDebugMessage(message: String) {
|
||||||
connection.sender.sendFakeChatMessage(RenderConstants.DEBUG_MESSAGES_PREFIX + message)
|
connection.sender.sendFakeChatMessage(RenderConstants.DEBUG_MESSAGES_PREFIX + message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterKeyBinding(it: ResourceLocation) {
|
|
||||||
keyBindingCallbacks.remove(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ class WorldRenderer(
|
|||||||
|
|
||||||
|
|
||||||
// register keybindings
|
// register keybindings
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.DEBUG_CLEAR_CHUNK_CACHE) { _, _ ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.DEBUG_CLEAR_CHUNK_CACHE) { _, _ ->
|
||||||
clearChunkCache()
|
clearChunkCache()
|
||||||
renderWindow.sendDebugMessage("Cleared chunk cache!")
|
renderWindow.sendDebugMessage("Cleared chunk cache!")
|
||||||
prepareWorld(world)
|
prepareWorld(world)
|
||||||
@ -324,7 +324,7 @@ class WorldRenderer(
|
|||||||
|
|
||||||
sectionMap[index] = meshCollection
|
sectionMap[index] = meshCollection
|
||||||
|
|
||||||
if (renderWindow.camera.frustum.containsChunk(chunkPosition, lowestBlockHeight, highestBlockHeight)) {
|
if (renderWindow.inputHandler.camera.frustum.containsChunk(chunkPosition, lowestBlockHeight, highestBlockHeight)) {
|
||||||
visibleChunks.getOrPut(chunkPosition, { ConcurrentHashMap() })[index] = meshCollection
|
visibleChunks.getOrPut(chunkPosition, { ConcurrentHashMap() })[index] = meshCollection
|
||||||
} else {
|
} else {
|
||||||
visibleChunks[chunkPosition]?.remove(index)
|
visibleChunks[chunkPosition]?.remove(index)
|
||||||
@ -392,7 +392,7 @@ class WorldRenderer(
|
|||||||
for ((chunkLocation, indexMap) in allChunkSections) {
|
for ((chunkLocation, indexMap) in allChunkSections) {
|
||||||
val visibleIndexMap: MutableMap<Int, ChunkMeshCollection> = Collections.synchronizedMap(ConcurrentHashMap())
|
val visibleIndexMap: MutableMap<Int, ChunkMeshCollection> = Collections.synchronizedMap(ConcurrentHashMap())
|
||||||
for ((index, mesh) in indexMap) {
|
for ((index, mesh) in indexMap) {
|
||||||
if (renderWindow.camera.frustum.containsChunk(chunkLocation, mesh.lowestBlockHeight, mesh.highestBlockHeight)) {
|
if (renderWindow.inputHandler.camera.frustum.containsChunk(chunkLocation, mesh.lowestBlockHeight, mesh.highestBlockHeight)) {
|
||||||
visibleIndexMap[index] = mesh
|
visibleIndexMap[index] = mesh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
|
|
||||||
registerDefaultElements()
|
registerDefaultElements()
|
||||||
|
|
||||||
renderWindow.registerKeyCallback(KeyBindingsNames.TOGGLE_HUD) { _, _ ->
|
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.TOGGLE_HUD) { _, _ ->
|
||||||
hudEnabled = !hudEnabled
|
hudEnabled = !hudEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
|
|
||||||
properties.toggleKeyBinding?.let {
|
properties.toggleKeyBinding?.let {
|
||||||
// register key binding
|
// register key binding
|
||||||
renderWindow.registerKeyCallback(it) { _, _ ->
|
renderWindow.inputHandler.registerKeyCallback(it) { _, _ ->
|
||||||
if (enabledHUDElement.contains(resourceLocation)) {
|
if (enabledHUDElement.contains(resourceLocation)) {
|
||||||
enabledHUDElement.remove(resourceLocation)
|
enabledHUDElement.remove(resourceLocation)
|
||||||
} else {
|
} else {
|
||||||
@ -142,7 +142,7 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
element.first.toggleKeyBinding?.let {
|
element.first.toggleKeyBinding?.let {
|
||||||
renderWindow.unregisterKeyBinding(it)
|
renderWindow.inputHandler.unregisterKeyBinding(it)
|
||||||
}
|
}
|
||||||
enabledHUDElement.remove(resourceLocation)
|
enabledHUDElement.remove(resourceLocation)
|
||||||
hudElements.remove(resourceLocation)
|
hudElements.remove(resourceLocation)
|
||||||
|
@ -40,10 +40,10 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr
|
|||||||
layout.addChild(Vec2i(0, 0), inputField)
|
layout.addChild(Vec2i(0, 0), inputField)
|
||||||
inputField.apply()
|
inputField.apply()
|
||||||
|
|
||||||
hudRenderer.renderWindow.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) { _, _ ->
|
hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) { _, _ ->
|
||||||
openChat()
|
openChat()
|
||||||
}
|
}
|
||||||
hudRenderer.renderWindow.registerKeyCallback(KeyBindingsNames.CLOSE_CHAT) { _, _ ->
|
hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.CLOSE_CHAT) { _, _ ->
|
||||||
closeChat()
|
closeChat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,12 +58,12 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr
|
|||||||
|
|
||||||
fun openChat() {
|
fun openChat() {
|
||||||
layout.addChild(Vec2i(0, 0), inputFieldBackground)
|
layout.addChild(Vec2i(0, 0), inputFieldBackground)
|
||||||
hudRenderer.renderWindow.currentKeyConsumer = inputField
|
hudRenderer.renderWindow.inputHandler.currentKeyConsumer = inputField
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closeChat() {
|
fun closeChat() {
|
||||||
layout.removeChild(inputFieldBackground)
|
layout.removeChild(inputFieldBackground)
|
||||||
inputField.clearText()
|
inputField.clearText()
|
||||||
hudRenderer.renderWindow.currentKeyConsumer = null
|
hudRenderer.renderWindow.inputHandler.currentKeyConsumer = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import de.bixilon.minosoft.util.UnitFormatter
|
|||||||
|
|
||||||
|
|
||||||
class HUDWorldDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer) {
|
class HUDWorldDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer) {
|
||||||
private val camera = hudRenderer.renderWindow.camera
|
private val camera = hudRenderer.renderWindow.inputHandler.camera
|
||||||
private val worldRenderer = hudRenderer.renderWindow.rendererMap[WorldRenderer.RESOURCE_LOCATION] as WorldRenderer?
|
private val worldRenderer = hudRenderer.renderWindow.rendererMap[WorldRenderer.RESOURCE_LOCATION] as WorldRenderer?
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -128,8 +128,8 @@ class HUDWorldDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getFacing(): String {
|
private fun getFacing(): String {
|
||||||
val yaw = hudRenderer.renderWindow.camera.playerEntity.rotation.yaw
|
val yaw = hudRenderer.renderWindow.inputHandler.camera.playerEntity.rotation.yaw
|
||||||
val pitch = hudRenderer.renderWindow.camera.playerEntity.rotation.pitch
|
val pitch = hudRenderer.renderWindow.inputHandler.camera.playerEntity.rotation.pitch
|
||||||
val direction = Directions.byDirection(camera.cameraFront)
|
val direction = Directions.byDirection(camera.cameraFront)
|
||||||
return "${Directions.byDirection(camera.cameraFront).name.toLowerCase()} ${direction.directionVector} (${formatRotation(yaw.toDouble())} / ${formatRotation(pitch.toDouble())})"
|
return "${Directions.byDirection(camera.cameraFront).name.toLowerCase()} ${direction.directionVector} (${formatRotation(yaw.toDouble())} / ${formatRotation(pitch.toDouble())})"
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ class PlayConnection(
|
|||||||
for (entity in world.entityIdMap.values) {
|
for (entity in world.entityIdMap.values) {
|
||||||
entity.computeTimeStep(deltaTime)
|
entity.computeTimeStep(deltaTime)
|
||||||
}
|
}
|
||||||
renderer?.renderWindow?.camera?.checkPosition()
|
renderer?.renderWindow?.inputHandler?.camera?.checkPosition()
|
||||||
velocityHandlerLastExecutionTime = currentTime
|
velocityHandlerLastExecutionTime = currentTime
|
||||||
}
|
}
|
||||||
TimeWorker.addTask(velocityHandlerTask)
|
TimeWorker.addTask(velocityHandlerTask)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user