rendering: screenshot saver, auto add missing hotkeys to config

This commit is contained in:
Bixilon 2021-02-28 14:58:35 +01:00
parent 42d9c9b592
commit 2b0f7a0c13
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 157 additions and 66 deletions

View File

@ -22,7 +22,7 @@ public class StaticConfiguration {
public static final boolean DEBUG_MODE = true; // if true, additional checks will be made to validate data, ... Decreases performance
public static final boolean BIOME_DEBUG_MODE = false; // colors all biomes according to the biome hashCode
public static final boolean DEBUG_SLOW_LOADING = false; // if true, many Thread.sleep will be executed and the start will be delayed (by a lot)
public static final boolean SHOW_LOG_MESSAGES_IN_CHAT = false; // prints all console messages in the chat box
public static final boolean SHOW_LOG_MESSAGES_IN_CHAT = true; // prints all console messages in the chat box
public static String CONFIG_FILENAME = "minosoft.json"; // Filename of minosoft's base configuration (located in AppData/Minosoft/config)
public static boolean SKIP_MOJANG_AUTHENTICATION; // disables all connections to mojang
public static boolean COLORED_LOG = true; // the log should be colored with ANSI (does not affect base components)

View File

@ -13,28 +13,49 @@
package de.bixilon.minosoft.config.config.game.controls
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEBUG_CLEAR_CHUNK_CACHE
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEBUG_MOUSE_CATCH
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEBUG_POLYGEN
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEBUG_SCREEN
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_BACKWARDS
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_FLY_DOWN
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_FLY_UP
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_FORWARD
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_LEFT
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_RIGHT
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.MOVE_SPRINT
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.QUIT_RENDERING
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.WHEN_IN_GAME
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.WHEN_PLAYER_IS_FLYING
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.ZOOM
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEFAULT_KEY_BINDINGS
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
data class KeyBindingsGameConfig(
val entries: MutableMap<ResourceLocation, KeyBinding> = mutableMapOf(
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)
}
}
}
}
object KeyBindingsNames {
val MOVE_FORWARD = ResourceLocation("minosoft:move_forward")
val MOVE_BACKWARDS = ResourceLocation("minosoft:move_backwards")
val MOVE_LEFT = ResourceLocation("minosoft:move_left")
val MOVE_RIGHT = ResourceLocation("minosoft:move_right")
val MOVE_SPRINT = ResourceLocation("minosoft:move_sprint")
val MOVE_FLY_UP = ResourceLocation("minosoft:move_fly_up")
val MOVE_FLY_DOWN = ResourceLocation("minosoft:move_fly_down")
val ZOOM = ResourceLocation("minosoft:zoom")
val QUIT_RENDERING = ResourceLocation("minosoft:quit_rendering")
val DEBUG_SCREEN = ResourceLocation("minosoft:debug_screen")
val DEBUG_CLEAR_CHUNK_CACHE = ResourceLocation("minosoft:debug_clear_chunk_cache")
val DEBUG_POLYGEN = ResourceLocation("minosoft:debug_polygen")
val DEBUG_MOUSE_CATCH = ResourceLocation("minosoft:debug_mouse_catch")
val WHEN_IN_GAME = ResourceLocation("minosoft:in_game")
val WHEN_PLAYER_IS_FLYING = ResourceLocation("minosoft:is_flying")
val TAKE_SCREENSHOT = ResourceLocation("minosoft:take_screenshot")
val DEFAULT_KEY_BINDINGS: Map<ResourceLocation, KeyBinding> = mapOf(
MOVE_FORWARD to KeyBinding(
mutableMapOf(
KeyAction.CHANGE to mutableSetOf(KeyCodes.KEY_W)
@ -116,27 +137,11 @@ data class KeyBindingsGameConfig(
),
mutableSetOf(mutableSetOf(WHEN_IN_GAME))
),
),
)
object KeyBindingsNames {
val MOVE_FORWARD = ResourceLocation("minosoft:move_forward")
val MOVE_BACKWARDS = ResourceLocation("minosoft:move_backwards")
val MOVE_LEFT = ResourceLocation("minosoft:move_left")
val MOVE_RIGHT = ResourceLocation("minosoft:move_right")
val MOVE_SPRINT = ResourceLocation("minosoft:move_sprint")
val MOVE_FLY_UP = ResourceLocation("minosoft:move_fly_up")
val MOVE_FLY_DOWN = ResourceLocation("minosoft:move_fly_down")
val ZOOM = ResourceLocation("minosoft:zoom")
val QUIT_RENDERING = ResourceLocation("minosoft:quit_rendering")
val DEBUG_SCREEN = ResourceLocation("minosoft:debug_screen")
val DEBUG_CLEAR_CHUNK_CACHE = ResourceLocation("minosoft:debug_clear_chunk_cache")
val DEBUG_POLYGEN = ResourceLocation("minosoft:debug_polygen")
val DEBUG_MOUSE_CATCH = ResourceLocation("minosoft:debug_mouse_catch")
val WHEN_IN_GAME = ResourceLocation("minosoft:in_game")
val WHEN_PLAYER_IS_FLYING = ResourceLocation("minosoft:is_flying")
TAKE_SCREENSHOT to KeyBinding(
mutableMapOf(
KeyAction.RELEASE to mutableSetOf(KeyCodes.KEY_F2)
),
mutableSetOf()
),
)
}

View File

@ -18,4 +18,6 @@ import de.bixilon.minosoft.data.mappings.ResourceLocation
class KeyBinding(
val action: MutableMap<KeyAction, MutableSet<KeyCodes>>,
val `when`: MutableSet<MutableSet<ResourceLocation>>,
)
) {
constructor(keyBinding: KeyBinding) : this(keyBinding.action.toMutableMap(), keyBinding.`when`.toMutableSet()) // ToDo: Deep copy
}

View File

@ -28,4 +28,6 @@ object RenderConstants {
val LILY_PAD_BLOCK_COLOR = RGBColor("#208030")
const val COLORMAP_SIZE = 255
const val DEBUG_MESSAGES_PREFIX = "§f[§e§lDEBUG§f] §9"
}

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.hud.elements.RenderStats
import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker
import de.bixilon.minosoft.modding.event.EventInvokerCallback
import de.bixilon.minosoft.modding.event.events.ConnectionStateChangeEvent
import de.bixilon.minosoft.modding.event.events.PacketReceiveEvent
@ -40,7 +41,7 @@ import org.lwjgl.system.MemoryStack
import org.lwjgl.system.MemoryUtil
import java.util.concurrent.ConcurrentLinkedQueue
class RenderWindow(private val connection: Connection, val rendering: Rendering) {
class RenderWindow(val connection: Connection, 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()
@ -59,6 +60,7 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
private var polygonEnabled = false
private var mouseCatch = !StaticConfiguration.DEBUG_MODE
private val screenshotTaker = ScreenshotTaker(this)
val tintColorCalculator = TintColorCalculator()
// all renderers
@ -259,27 +261,8 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
}
})
registerKeyCallback(KeyBindingsNames.DEBUG_POLYGEN) { _: KeyCodes, _: KeyAction ->
polygonEnabled = !polygonEnabled
glPolygonMode(GL_FRONT_AND_BACK, if (polygonEnabled) {
GL_LINE
} else {
GL_FILL
})
connection.sender.sendFakeChatMessage("§f[§e§lDEBUG§f] §9Toggled polygen mode!")
}
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH) { _: KeyCodes, _: KeyAction ->
mouseCatch = !mouseCatch
if (mouseCatch) {
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
} else {
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_NORMAL)
}
connection.sender.sendFakeChatMessage("§f[§e§lDEBUG§f] §9Toggled mouse catch!")
}
registerKeyCallback(KeyBindingsNames.QUIT_RENDERING) { _: KeyCodes, _: KeyAction ->
glfwSetWindowShouldClose(windowId, true)
}
registerGlobalKeyCombinations()
hudRenderer.screenChangeResizeCallback(screenWidth, screenHeight)
@ -296,6 +279,33 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
glfwShowWindow(windowId)
}
private fun registerGlobalKeyCombinations() {
registerKeyCallback(KeyBindingsNames.DEBUG_POLYGEN) { _: KeyCodes, _: KeyAction ->
polygonEnabled = !polygonEnabled
glPolygonMode(GL_FRONT_AND_BACK, if (polygonEnabled) {
GL_LINE
} else {
GL_FILL
})
sendDebugMessage("Toggled polygen mode!")
}
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH) { _: 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)
}
registerKeyCallback(KeyBindingsNames.TAKE_SCREENSHOT) { _: KeyCodes, _: KeyAction ->
screenshotTaker.takeScreenshot()
}
}
fun startRenderLoop() {
while (!glfwWindowShouldClose(windowId)) {
if (renderingStatus == RenderingStates.PAUSED) {
@ -382,4 +392,8 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
fun setSkyColor(color: RGBColor) {
glClearColor(color.floatRed, color.floatGreen, color.floatBlue, 1.0f)
}
fun sendDebugMessage(message: String) {
connection.sender.sendFakeChatMessage(RenderConstants.DEBUG_MESSAGES_PREFIX + message)
}
}

View File

@ -0,0 +1,71 @@
/*
* 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.util
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.util.Util
import de.matthiasmann.twl.utils.PNGDecoder
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GL11.*
import java.awt.image.BufferedImage
import java.io.File
import java.nio.ByteBuffer
import java.text.SimpleDateFormat
import javax.imageio.ImageIO
class ScreenshotTaker(
private val renderWindow: RenderWindow,
) {
fun takeScreenshot() {
try {
val basePath = "${StaticConfiguration.HOME_DIRECTORY}/screenshots/${renderWindow.connection.address.hostname}/${DATE_FORMATTER.format(System.currentTimeMillis())}"
Util.createParentFolderIfNotExist(basePath)
var path = "$basePath.png"
var i = 1
while (File(path).exists()) {
path = "${basePath}_${i++}.png"
}
val width = renderWindow.screenWidth
val height = renderWindow.screenHeight
val buffer: ByteBuffer = BufferUtils.createByteBuffer(width * height * PNGDecoder.Format.RGBA.numComponents)
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer)
val bufferedImage = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
for (x in 0 until width) {
for (y in 0 until height) {
val index: Int = (x + width * y) * 4
val red: Int = buffer[index].toInt() and 0xFF
val green: Int = buffer[index + 1].toInt() and 0xFF
val blue: Int = buffer[index + 2].toInt() and 0xFF
bufferedImage.setRGB(x, height - (y + 1), 0xFF shl 24 or (red shl 16) or (green shl 8) or blue)
}
}
ImageIO.write(bufferedImage, "png", File(path))
renderWindow.sendDebugMessage("§aScreenshot saved to §f$path")
} catch (exception: Exception) {
exception.printStackTrace()
renderWindow.sendDebugMessage("§cFailed to make a screenshot!")
}
}
companion object {
private val DATE_FORMATTER = SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")
}
}

View File

@ -28,9 +28,6 @@ class PacketUpdateLight : ClientboundPacket() {
override fun read(buffer: InByteBuffer): Boolean {
position = ChunkPosition(buffer.readVarInt(), buffer.readVarInt())
if (position == ChunkPosition(-6, 20)) {
Log.debug("")
}
if (buffer.versionId >= ProtocolVersions.V_1_16_PRE3) {
val trustEdges = buffer.readBoolean()
}