keybindings: Fix STICKY_INVERTED, hud toggle keybindings

This commit is contained in:
Bixilon 2021-09-11 19:29:12 +02:00
parent 65744d625f
commit 289a0875a3
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 139 additions and 112 deletions

View File

@ -13,19 +13,9 @@
package de.bixilon.minosoft.config.config.game.controls
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEFAULT_KEY_BINDINGS
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.data.registries.ResourceLocation
data class KeyBindingsGameConfig(
val entries: MutableMap<ResourceLocation, KeyBinding> = mutableMapOf(),
) {
init {
for ((resourceLocation, keyBinding) in DEFAULT_KEY_BINDINGS) {
if (!entries.containsKey(resourceLocation)) {
// add key binding
entries[resourceLocation] = KeyBinding(keyBinding)
}
}
}
}
)

View File

@ -1,57 +0,0 @@
/*
* 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.config.config.game.controls
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.registries.ResourceLocation
@Deprecated(message = "Use new system with providing default key bindings when registering instead of \"pre registering\" the key")
object KeyBindingsNames {
val TOGGLE_DEBUG_SCREEN = ResourceLocation("minosoft:toggle_debug_screen")
val DEBUG_MOUSE_CATCH = ResourceLocation("minosoft:debug_mouse_catch")
val TOGGLE_HUD = ResourceLocation("minosoft:toggle_hud")
val OPEN_CHAT = ResourceLocation("minosoft:open_chat")
val CLOSE = ResourceLocation("minosoft:close")
val DEFAULT_KEY_BINDINGS: Map<ResourceLocation, KeyBinding> = mapOf(
TOGGLE_DEBUG_SCREEN to KeyBinding(
mutableMapOf(
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_F3),
),
),
TOGGLE_HUD to KeyBinding(
mutableMapOf(
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_F1),
),
),
OPEN_CHAT to KeyBinding(
mutableMapOf(
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_T),
),
),
CLOSE to KeyBinding(
mutableMapOf(
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_ESCAPE),
),
ignoreConsumer = true,
),
)
}

View File

@ -39,7 +39,7 @@ enum class KeyAction {
MODIFIER,
/**
* Pressing the key makes it sticky, you have to press it again to make it not pressed anymore
* Pressing the key makes it sticky, you have to press it again to make it not pressed anymore. Initially not pressed.
*/
STICKY,

View File

@ -49,6 +49,7 @@ import de.bixilon.minosoft.util.CountUpAndDownLatch
import de.bixilon.minosoft.util.KUtil.decide
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.KUtil.unsafeCast
import de.bixilon.minosoft.util.MMath.round10
import de.bixilon.minosoft.util.Queue
import de.bixilon.minosoft.util.Stopwatch
@ -219,7 +220,7 @@ class RenderWindow(
}
private fun registerGlobalKeyCombinations() {
inputHandler.registerKeyCallback("minosoft:debug_polygon".toResourceLocation(), KeyBinding(
inputHandler.registerKeyCallback("minosoft:enable_debug_polygon".toResourceLocation(), KeyBinding(
mutableMapOf(
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F4),
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_P),
@ -361,6 +362,6 @@ class RenderWindow(
}
operator fun <T : Renderer> get(renderer: RendererBuilder<T>): T? {
return rendererMap[renderer.RESOURCE_LOCATION] as T?
return rendererMap[renderer.RESOURCE_LOCATION].unsafeCast()
}
}

View File

@ -14,20 +14,28 @@
package de.bixilon.minosoft.gui.rendering.gui.hud
import de.bixilon.minosoft.Minosoft
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.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.DebugHUD
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.HUD
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.DebugHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.synchronizedListOf
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.glm
import glm_.mat4x4.Mat4
import glm_.vec2.Vec2
@ -41,25 +49,50 @@ class HUDRenderer(
private lateinit var mesh: GUIMesh
var scaledSize: Vec2i = renderWindow.window.size
private var matrix: Mat4 = Mat4()
private var enabled = true
val hud: MutableList<HUD<*>> = synchronizedListOf(
DebugHUD(this),
)
private val hudElements: MutableMap<ResourceLocation, HUDElement<*>> = synchronizedMapOf()
private var lastTickTime = 0L
fun registerElement(hudBuilder: HUDBuilder<*>) {
val hudElement = hudBuilder.build(this)
hudElements[hudBuilder.RESOURCE_LOCATION] = hudElement
val toggleKeyBinding = hudBuilder.ENABLE_KEY_BINDING ?: return
val toggleKeyBindingName = hudBuilder.ENABLE_KEY_BINDING_NAME ?: return
// ToDo: Default disabled elements like the debug screen?
renderWindow.inputHandler.registerKeyCallback(toggleKeyBindingName, toggleKeyBinding) { hudElement.enabled = it }
}
private fun registerDefaultElements() {
registerElement(DebugHUDElement)
}
override fun init() {
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
scaledSize = Vec2i(Vec2(it.size) / Minosoft.config.config.game.hud.scale)
matrix = glm.ortho(0.0f, scaledSize.x.toFloat(), scaledSize.y.toFloat(), 0.0f)
for (hud in hud) {
hud.layout?.onParentChange()
for (element in hudElements.toSynchronizedMap().values) {
element.layout?.onParentChange()
}
})
registerDefaultElements()
for (hud in this.hud) {
hud.init()
for (element in this.hudElements.toSynchronizedMap().values) {
element.init()
}
renderWindow.inputHandler.registerKeyCallback("minosoft:enable_hud".toResourceLocation(), KeyBinding(
mutableMapOf(
KeyAction.STICKY_INVERTED to mutableSetOf(KeyCodes.KEY_F1),
),
)) {
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Toggled hud: $it" }
enabled = it
}
}
@ -67,23 +100,30 @@ class HUDRenderer(
shader.load()
renderWindow.textureManager.staticTextures.use(shader)
for (hud in this.hud) {
hud.postInit()
for (element in this.hudElements.toSynchronizedMap().values) {
element.postInit()
}
}
override fun draw() {
if (!enabled) {
return
}
renderWindow.renderSystem.reset()
if (this::mesh.isInitialized) {
mesh.unload()
}
mesh = GUIMesh(renderWindow, matrix)
val hudElements = hudElements.toSynchronizedMap().values
val time = System.currentTimeMillis()
if (time - lastTickTime > ProtocolDefinition.TICK_TIME) {
for (hud in this.hud) {
hud.tick()
for (element in hudElements) {
if (!element.enabled) {
continue
}
element.tick()
}
lastTickTime = time
@ -91,12 +131,12 @@ class HUDRenderer(
// ToDo: size > maxSize
for (hud in this.hud) {
val z = 0
val offset = Vec2i.EMPTY // ToDo: Element positioning
hud.layout?.render(offset, z, mesh)
hud.draw(offset, z, mesh)
for (element in hudElements) {
if (!element.enabled) {
continue
}
element.layout?.render(element.layoutOffset ?: Vec2i.EMPTY, 0, mesh)
element.draw(mesh)
}
mesh.load()
@ -107,7 +147,7 @@ class HUDRenderer(
}
companion object : RendererBuilder<HUDRenderer> {
override val RESOURCE_LOCATION = ResourceLocation("minosoft:hud_renderer")
override val RESOURCE_LOCATION = "minosoft:hud_renderer".toResourceLocation()
override fun build(connection: PlayConnection, renderWindow: RenderWindow): HUDRenderer {
return HUDRenderer(connection, renderWindow)

View File

@ -14,14 +14,17 @@
package de.bixilon.minosoft.gui.rendering.gui.hud.hud
import de.bixilon.minosoft.Minosoft
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.abilities.Gamemodes
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameMoveChangeGameEventHandler
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.world.Chunk
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.block.WorldRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
@ -43,6 +46,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.terminal.RunConfiguration
import de.bixilon.minosoft.util.GitInfo
import de.bixilon.minosoft.util.KUtil.format
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.MMath.round10
import de.bixilon.minosoft.util.SystemInformation
import de.bixilon.minosoft.util.UnitFormatter.formatBytes
@ -50,8 +54,7 @@ import glm_.vec2.Vec2i
import glm_.vec4.Vec4i
import kotlin.math.abs
class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
override val renderWindow: RenderWindow = hudRenderer.renderWindow
class DebugHUDElement(hudRenderer: HUDRenderer) : HUDElement<GridLayout>(hudRenderer) {
private val connection = renderWindow.connection
override val layout = GridLayout(hudRenderer, Vec2i(3, 1)).apply {
columnConstraints[0].apply {
@ -276,4 +279,18 @@ class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
super.tick()
}
}
companion object : HUDBuilder<DebugHUDElement> {
override val RESOURCE_LOCATION: ResourceLocation = "minosoft:debug_hud".toResourceLocation()
override val ENABLE_KEY_BINDING_NAME: ResourceLocation = "minosoft:enable_debug_hud".toResourceLocation()
override val ENABLE_KEY_BINDING: KeyBinding = KeyBinding(
mutableMapOf(
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_F3),
),
)
override fun build(hudRenderer: HUDRenderer): DebugHUDElement {
return DebugHUDElement(hudRenderer)
}
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.rendering.gui.hud.hud
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.data.registries.CompanionResourceLocation
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
interface HUDBuilder<T : HUDElement<*>> : CompanionResourceLocation {
val ENABLE_KEY_BINDING_NAME: ResourceLocation?
get() = null
val ENABLE_KEY_BINDING: KeyBinding?
get() = null
fun build(hudRenderer: HUDRenderer): T
}

View File

@ -15,22 +15,27 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.hud
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.gui.elements.layout.Layout
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import glm_.vec2.Vec2i
interface HUD<T : Layout> {
val renderWindow: RenderWindow
abstract class HUDElement<T : Layout>(val hudRenderer: HUDRenderer) {
val renderWindow: RenderWindow = hudRenderer.renderWindow
var enabled = true
val layout: T?
open val layout: T?
get() = null
fun init() {}
open val layoutOffset: Vec2i?
get() = null
fun postInit() {}
open fun init() {}
fun draw(offset: Vec2i, z: Int, consumer: GUIVertexConsumer) {}
open fun postInit() {}
fun tick() {
open fun draw(consumer: GUIVertexConsumer) {}
open fun tick() {
layout?.tick()
}
}

View File

@ -14,7 +14,6 @@
package de.bixilon.minosoft.gui.rendering.input.key
import de.bixilon.minosoft.Minosoft
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
@ -32,6 +31,7 @@ import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil.decide
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class RenderWindowInputHandler(
val renderWindow: RenderWindow,
@ -50,7 +50,7 @@ class RenderWindowInputHandler(
val leftClickHandler = LeftClickHandler(renderWindow)
init {
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH, KeyBinding(
registerKeyCallback("minosoft:debug_mouse_catch".toResourceLocation(), KeyBinding(
mutableMapOf(
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F4),
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_M),
@ -142,11 +142,7 @@ class RenderWindowInputHandler(
checksRun++
}
fun checkSticky(keys: MutableSet<KeyCodes>, invert: Boolean) {
var alreadyActive = keyBindingsDown.contains(resourceLocation)
if (invert) {
alreadyActive = !alreadyActive
}
fun checkSticky(keys: MutableSet<KeyCodes>) {
checksRun++
if (!keys.contains(keyCode)) {
thisIsChange = false
@ -156,15 +152,15 @@ class RenderWindowInputHandler(
thisIsChange = false
return
}
thisKeyBindingDown = !alreadyActive
thisKeyBindingDown = !keyBindingsDown.contains(resourceLocation)
}
pair.keyBinding.action[KeyAction.STICKY]?.let {
checkSticky(it, false)
checkSticky(it)
}
pair.keyBinding.action[KeyAction.STICKY_INVERTED]?.let {
checkSticky(it, true)
checkSticky(it)
}
pair.keyBinding.action[KeyAction.DOUBLE_PRESS]?.let {
@ -239,6 +235,13 @@ class RenderWindowInputHandler(
callback(it)
}
}
// Instant fire
if (keyBinding.action.containsKey(KeyAction.STICKY)) {
callback(false)
} else if (keyBinding.action.containsKey(KeyAction.STICKY_INVERTED)) {
keyBindingsDown += resourceLocation
callback(true)
}
}
fun registerCheckCallback(vararg checks: Pair<ResourceLocation, KeyBinding>) {