From 414a318cab78ea25b2bc42bf0c37e6487f8e8553 Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Thu, 6 Aug 2026 21:36:00 -0400 Subject: [PATCH 1/4] Fix POLYPLUS2-XT --- .../internal/ui/compose/ComposeScreen.kt | 129 ++++++++++-------- .../internal/ui/compose/ComposeSupport.kt | 12 +- 2 files changed, 81 insertions(+), 60 deletions(-) diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt index e658ccc2f..89741eef8 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt @@ -140,6 +140,17 @@ abstract class ComposeScreen( } } + private inline fun sendKeyEventSafely(build: () -> androidx.compose.ui.input.key.KeyEvent): Boolean { + val event = try { + build() + } catch (t: Throwable) { + ComposeSupport.recordSceneFailure(t) + reportUnavailableAndClose() + return false + } + return withScene { it.sendKeyEvent(event) } ?: false + } + private fun poisonScene(cause: Throwable) { if (scenePoisoned) return scenePoisoned = true @@ -504,26 +515,26 @@ abstract class ComposeScreen( val eventLocation = KeyEvent.KEY_LOCATION_UNKNOWN val eventCode = 0 - val composeEvent = androidx.compose.ui.input.key.KeyEvent( - key = androidx.compose.ui.input.key.Key(awtCode), - type = KeyEventType.KeyDown, - codePoint = codepoint, - isCtrlPressed = modifiers.ctrlDown(), - isShiftPressed = modifiers.shiftDown(), - isAltPressed = modifiers.altDown(), - isMetaPressed = modifiers.superDown(), - nativeEvent = KeyEvent( - dummyComponent, - eventType, - System.currentTimeMillis(), - modifiersToAwt(modifiers), - eventCode, - char, - eventLocation + val handled = sendKeyEventSafely { + androidx.compose.ui.input.key.KeyEvent( + key = androidx.compose.ui.input.key.Key(awtCode), + type = KeyEventType.KeyDown, + codePoint = codepoint, + isCtrlPressed = modifiers.ctrlDown(), + isShiftPressed = modifiers.shiftDown(), + isAltPressed = modifiers.altDown(), + isMetaPressed = modifiers.superDown(), + nativeEvent = KeyEvent( + dummyComponent, + eventType, + System.currentTimeMillis(), + modifiersToAwt(modifiers), + eventCode, + char, + eventLocation + ) ) - ) - - val handled = withScene { it.sendKeyEvent(composeEvent) } ?: false + } //? >= 1.21.10 { return handled || super.charTyped(event) //? } else { @@ -552,28 +563,28 @@ abstract class ComposeScreen( val eventType = KeyEvent.KEY_PRESSED val eventLocation = glfwKeyLocation(key) - val composeEvent = androidx.compose.ui.input.key.KeyEvent( - key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), - type = KeyEventType.KeyDown, - // Carry the raw GLFW key code so consumers (e.g. KeybindOption) can recover it losslessly; - // the AWT round-trip in the Key collapses unmapped keys to VK_UNDEFINED. - codePoint = key, - isCtrlPressed = modifiers.ctrlDown(), - isShiftPressed = modifiers.shiftDown(), - isAltPressed = modifiers.altDown(), - isMetaPressed = modifiers.superDown(), - nativeEvent = KeyEvent( - dummyComponent, - eventType, - System.currentTimeMillis(), - modifiersToAwt(modifiers), - awtCode, - Char(0), - eventLocation + val handled = sendKeyEventSafely { + androidx.compose.ui.input.key.KeyEvent( + key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), + type = KeyEventType.KeyDown, + // Carry the raw GLFW key code so consumers (e.g. KeybindOption) can recover it losslessly; + // the AWT round-trip in the Key collapses unmapped keys to VK_UNDEFINED. + codePoint = key, + isCtrlPressed = modifiers.ctrlDown(), + isShiftPressed = modifiers.shiftDown(), + isAltPressed = modifiers.altDown(), + isMetaPressed = modifiers.superDown(), + nativeEvent = KeyEvent( + dummyComponent, + eventType, + System.currentTimeMillis(), + modifiersToAwt(modifiers), + awtCode, + Char(0), + eventLocation + ) ) - ) - - val handled = withScene { it.sendKeyEvent(composeEvent) } ?: false + } //? >= 1.21.10 { return handled || super.keyPressed(event) //? } else { @@ -592,26 +603,26 @@ abstract class ComposeScreen( val awtCode = glfwToAwtKeyCode(key) val eventLocation = glfwKeyLocation(key) - val composeEvent = androidx.compose.ui.input.key.KeyEvent( - key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), - type = KeyEventType.KeyUp, - codePoint = key, - isCtrlPressed = modifiers.ctrlDown(), - isShiftPressed = modifiers.shiftDown(), - isAltPressed = modifiers.altDown(), - isMetaPressed = modifiers.superDown(), - nativeEvent = KeyEvent( - dummyComponent, - KeyEvent.KEY_RELEASED, - System.currentTimeMillis(), - modifiersToAwt(modifiers), - awtCode, - KeyEvent.CHAR_UNDEFINED, - eventLocation + val handled = sendKeyEventSafely { + androidx.compose.ui.input.key.KeyEvent( + key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), + type = KeyEventType.KeyUp, + codePoint = key, + isCtrlPressed = modifiers.ctrlDown(), + isShiftPressed = modifiers.shiftDown(), + isAltPressed = modifiers.altDown(), + isMetaPressed = modifiers.superDown(), + nativeEvent = KeyEvent( + dummyComponent, + KeyEvent.KEY_RELEASED, + System.currentTimeMillis(), + modifiersToAwt(modifiers), + awtCode, + KeyEvent.CHAR_UNDEFINED, + eventLocation + ) ) - ) - - val handled = withScene { it.sendKeyEvent(composeEvent) } ?: false + } //? >= 1.21.10 { return handled || super.keyReleased(event) //? } else { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt index 9a1718e9e..d91ba4322 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt @@ -58,7 +58,17 @@ object ComposeSupport { return "OneConfig's UI can't start on $osLabel: a required library (AWT or Skiko) is " + "missing from this Java runtime. Try a full JDK/JRE." } - return null + return awtInitFailure() + } + + private fun awtInitFailure(): String? = try { + Class.forName("java.awt.event.KeyEvent", true, ComposeSupport::class.java.classLoader) + null + } catch (t: Throwable) { + LOG.error("AWT failed to initialize on this runtime; the OneConfig UI has been disabled.", t) + "OneConfig's UI can't start on $osLabel: this Java runtime has no working AWT support " + + "(java.awt.Toolkit failed to initialize). Try a full JDK/JRE rather than a headless " + + "or trimmed-down one." } private const val DISABLE_PROPERTY = "oneconfig.ui.disable" From 12dee67c52c47c3cc59c7db733074888ab3452f7 Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Thu, 6 Aug 2026 21:38:47 -0400 Subject: [PATCH 2/4] Fix POLYPLUS2-XT --- .../internal/ui/compose/ComposeScreen.kt | 129 ++++++++++-------- .../internal/ui/compose/ComposeSupport.kt | 12 +- 2 files changed, 81 insertions(+), 60 deletions(-) diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt index e658ccc2f..89741eef8 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt @@ -140,6 +140,17 @@ abstract class ComposeScreen( } } + private inline fun sendKeyEventSafely(build: () -> androidx.compose.ui.input.key.KeyEvent): Boolean { + val event = try { + build() + } catch (t: Throwable) { + ComposeSupport.recordSceneFailure(t) + reportUnavailableAndClose() + return false + } + return withScene { it.sendKeyEvent(event) } ?: false + } + private fun poisonScene(cause: Throwable) { if (scenePoisoned) return scenePoisoned = true @@ -504,26 +515,26 @@ abstract class ComposeScreen( val eventLocation = KeyEvent.KEY_LOCATION_UNKNOWN val eventCode = 0 - val composeEvent = androidx.compose.ui.input.key.KeyEvent( - key = androidx.compose.ui.input.key.Key(awtCode), - type = KeyEventType.KeyDown, - codePoint = codepoint, - isCtrlPressed = modifiers.ctrlDown(), - isShiftPressed = modifiers.shiftDown(), - isAltPressed = modifiers.altDown(), - isMetaPressed = modifiers.superDown(), - nativeEvent = KeyEvent( - dummyComponent, - eventType, - System.currentTimeMillis(), - modifiersToAwt(modifiers), - eventCode, - char, - eventLocation + val handled = sendKeyEventSafely { + androidx.compose.ui.input.key.KeyEvent( + key = androidx.compose.ui.input.key.Key(awtCode), + type = KeyEventType.KeyDown, + codePoint = codepoint, + isCtrlPressed = modifiers.ctrlDown(), + isShiftPressed = modifiers.shiftDown(), + isAltPressed = modifiers.altDown(), + isMetaPressed = modifiers.superDown(), + nativeEvent = KeyEvent( + dummyComponent, + eventType, + System.currentTimeMillis(), + modifiersToAwt(modifiers), + eventCode, + char, + eventLocation + ) ) - ) - - val handled = withScene { it.sendKeyEvent(composeEvent) } ?: false + } //? >= 1.21.10 { return handled || super.charTyped(event) //? } else { @@ -552,28 +563,28 @@ abstract class ComposeScreen( val eventType = KeyEvent.KEY_PRESSED val eventLocation = glfwKeyLocation(key) - val composeEvent = androidx.compose.ui.input.key.KeyEvent( - key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), - type = KeyEventType.KeyDown, - // Carry the raw GLFW key code so consumers (e.g. KeybindOption) can recover it losslessly; - // the AWT round-trip in the Key collapses unmapped keys to VK_UNDEFINED. - codePoint = key, - isCtrlPressed = modifiers.ctrlDown(), - isShiftPressed = modifiers.shiftDown(), - isAltPressed = modifiers.altDown(), - isMetaPressed = modifiers.superDown(), - nativeEvent = KeyEvent( - dummyComponent, - eventType, - System.currentTimeMillis(), - modifiersToAwt(modifiers), - awtCode, - Char(0), - eventLocation + val handled = sendKeyEventSafely { + androidx.compose.ui.input.key.KeyEvent( + key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), + type = KeyEventType.KeyDown, + // Carry the raw GLFW key code so consumers (e.g. KeybindOption) can recover it losslessly; + // the AWT round-trip in the Key collapses unmapped keys to VK_UNDEFINED. + codePoint = key, + isCtrlPressed = modifiers.ctrlDown(), + isShiftPressed = modifiers.shiftDown(), + isAltPressed = modifiers.altDown(), + isMetaPressed = modifiers.superDown(), + nativeEvent = KeyEvent( + dummyComponent, + eventType, + System.currentTimeMillis(), + modifiersToAwt(modifiers), + awtCode, + Char(0), + eventLocation + ) ) - ) - - val handled = withScene { it.sendKeyEvent(composeEvent) } ?: false + } //? >= 1.21.10 { return handled || super.keyPressed(event) //? } else { @@ -592,26 +603,26 @@ abstract class ComposeScreen( val awtCode = glfwToAwtKeyCode(key) val eventLocation = glfwKeyLocation(key) - val composeEvent = androidx.compose.ui.input.key.KeyEvent( - key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), - type = KeyEventType.KeyUp, - codePoint = key, - isCtrlPressed = modifiers.ctrlDown(), - isShiftPressed = modifiers.shiftDown(), - isAltPressed = modifiers.altDown(), - isMetaPressed = modifiers.superDown(), - nativeEvent = KeyEvent( - dummyComponent, - KeyEvent.KEY_RELEASED, - System.currentTimeMillis(), - modifiersToAwt(modifiers), - awtCode, - KeyEvent.CHAR_UNDEFINED, - eventLocation + val handled = sendKeyEventSafely { + androidx.compose.ui.input.key.KeyEvent( + key = androidx.compose.ui.input.key.Key(awtCode, eventLocation), + type = KeyEventType.KeyUp, + codePoint = key, + isCtrlPressed = modifiers.ctrlDown(), + isShiftPressed = modifiers.shiftDown(), + isAltPressed = modifiers.altDown(), + isMetaPressed = modifiers.superDown(), + nativeEvent = KeyEvent( + dummyComponent, + KeyEvent.KEY_RELEASED, + System.currentTimeMillis(), + modifiersToAwt(modifiers), + awtCode, + KeyEvent.CHAR_UNDEFINED, + eventLocation + ) ) - ) - - val handled = withScene { it.sendKeyEvent(composeEvent) } ?: false + } //? >= 1.21.10 { return handled || super.keyReleased(event) //? } else { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt index 9a1718e9e..d91ba4322 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSupport.kt @@ -58,7 +58,17 @@ object ComposeSupport { return "OneConfig's UI can't start on $osLabel: a required library (AWT or Skiko) is " + "missing from this Java runtime. Try a full JDK/JRE." } - return null + return awtInitFailure() + } + + private fun awtInitFailure(): String? = try { + Class.forName("java.awt.event.KeyEvent", true, ComposeSupport::class.java.classLoader) + null + } catch (t: Throwable) { + LOG.error("AWT failed to initialize on this runtime; the OneConfig UI has been disabled.", t) + "OneConfig's UI can't start on $osLabel: this Java runtime has no working AWT support " + + "(java.awt.Toolkit failed to initialize). Try a full JDK/JRE rather than a headless " + + "or trimmed-down one." } private const val DISABLE_PROPERTY = "oneconfig.ui.disable" From 35bde290f746fbed8aad0b97a3e4eba76d148e0d Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Fri, 7 Aug 2026 00:28:32 -0400 Subject: [PATCH 3/4] Fix #936 --- .../internal/ui/components/settings/DraggableListOption.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/settings/DraggableListOption.kt b/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/settings/DraggableListOption.kt index ef5cc37a7..99eb626f4 100644 --- a/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/settings/DraggableListOption.kt +++ b/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/settings/DraggableListOption.kt @@ -70,12 +70,12 @@ fun DraggableListOption(data: DraggableListOptionData) { // Current ordered items. When checkable, includes disabled items appended after enabled ones. var items by remember(data.prop) { - val ordered = propValueList(data.prop).ifEmpty { allOptions } + val ordered = propValueList(data.prop) val result = if (data.checkable) { val enabledSet = ordered.toSet() ordered + allOptions.filter { it !in enabledSet } } else { - ordered + ordered.ifEmpty { allOptions } } mutableStateOf(result.map { ListEntry(idGen[0]++, it) }) } @@ -83,7 +83,7 @@ fun DraggableListOption(data: DraggableListOptionData) { // Enabled slot ids (checkable only — property value = enabled items in order) var enabledIds by remember(data.prop) { if (!data.checkable) return@remember mutableStateOf(emptySet()) - val enabled = propValueList(data.prop).ifEmpty { allOptions }.toSet() + val enabled = propValueList(data.prop).toSet() mutableStateOf(items.filter { it.value in enabled }.map { it.id }.toSet()) } From df338a278d191341d590d0c14f743b73cceab943 Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Fri, 7 Aug 2026 01:00:19 -0400 Subject: [PATCH 4/4] Fix POLYPLUS2-XR & Fix POLYPLUS2-49 --- .../internal/ui/compose/ComposeScreen.kt | 43 +++++++---- .../internal/ui/hud/LegacyHudOffscreen.kt | 11 ++- .../internal/ui/hud/LegacyHudRenderer.kt | 76 +++++++++++++------ 3 files changed, 86 insertions(+), 44 deletions(-) diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt index 89741eef8..348067ab4 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt @@ -154,7 +154,11 @@ abstract class ComposeScreen( private fun poisonScene(cause: Throwable) { if (scenePoisoned) return scenePoisoned = true - SkiaCtx.clearComposeFrame() + try { + SkiaCtx.clearComposeFrame() + } catch (t: Throwable) { + cause.addSuppressed(t) + } LOGGER.error( "Compose scene for ${this::class.java.simpleName} failed and has been discarded; " + "it will be rebuilt on the next frame.", @@ -403,22 +407,29 @@ abstract class ComposeScreen( if (liveScene() == null) return - val renderBlock = Runnable { - val canvas = SkiaCtx.canvas - val pixelRatio = surfaceScale() - val mode = OneConfigConfig.reducedResFilter - val amount = OneConfigConfig.uiSharpening - val filter = mode != 0 && amount > 0f && - DesktopHelper.isMac && osUpscaleFactor() > 1.05f - val depth = canvas.save() - if (filter) canvas.saveLayer(null, filterPaint(mode, amount)) - if (pixelRatio != 1f) { - canvas.scale(pixelRatio, pixelRatio) - } - if (withScene { it.render(canvas.asComposeCanvas(), System.nanoTime()) } != null) { - sceneRebuilds = 0 + val renderBlock = Runnable { + try { + val canvas = SkiaCtx.canvas + val pixelRatio = surfaceScale() + val mode = OneConfigConfig.reducedResFilter + val amount = OneConfigConfig.uiSharpening + val filter = mode != 0 && amount > 0f && + DesktopHelper.isMac && osUpscaleFactor() > 1.05f + val depth = canvas.save() + try { + if (filter) canvas.saveLayer(null, filterPaint(mode, amount)) + if (pixelRatio != 1f) { + canvas.scale(pixelRatio, pixelRatio) + } + if (withScene { it.render(canvas.asComposeCanvas(), System.nanoTime()) } != null) { + sceneRebuilds = 0 + } + } finally { + canvas.restoreToCount(depth) + } + } catch (t: Throwable) { + poisonScene(t) } - canvas.restoreToCount(depth) } val wasDirty = sceneDirty diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt index e7b68a830..20916c74a 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt @@ -113,10 +113,13 @@ object LegacyHudOffscreen { hud.renderedH = hud.height * scale val pose = ext.pose() pose.pushMatrix() - pose.translate(hud.x, hud.y) - if (scale != 1f) pose.scale(scale, scale) - hud.render(ext) - pose.popMatrix() + try { + pose.translate(hud.x, hud.y) + if (scale != 1f) pose.scale(scale, scale) + hud.render(ext) + } finally { + pose.popMatrix() + } } catch (t: Throwable) { LOG.debug("legacy hud render (record) failed", t) } diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt index 5e809721a..877b7eabb 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt @@ -5,6 +5,8 @@ import net.minecraft.client.gui.GuiGraphicsExtractor import org.polyfrost.oneconfig.api.hud.v1.HudManager import org.polyfrost.oneconfig.api.hud.v1.LegacyHud +private val LOGGER = org.apache.logging.log4j.LogManager.getLogger("OneConfig/HUD-Render") + object LegacyHudRenderer { /** * Reused across frames to hold the HUDs drawn this frame. HUD update/render callbacks may add to or @@ -12,6 +14,22 @@ object LegacyHudRenderer { */ private val frame = ArrayList() + /** + * HUDs that have already had a failure logged. A HUD that throws usually throws every frame, so only the + * first failure is reported to avoid flooding the log at framerate. Weak so a removed HUD can be collected. + */ + private val reportedFailures = + java.util.Collections.newSetFromMap(java.util.WeakHashMap()) + + private fun reportFailure(hud: LegacyHud, e: Throwable) { + if (!reportedFailures.add(hud)) return + LOGGER.error( + "Failed to render HUD ${hud.title}; it was dropped from this frame and further failures " + + "from it will not be logged", + e, + ) + } + fun renderLive(graphics: GuiGraphicsExtractor) { renderLiveHuds(graphics) if (CompatOverlayRenderer.oneConfigScreenOpen()) CompatOverlayRenderer.render(graphics) @@ -33,32 +51,42 @@ object LegacyHudRenderer { frame.add(hud) } for (hud in frame) { - HudManager.updateIfDue(hud) - val hudScale = hud.effectiveScale - val (mw, mh) = hud.frameMinimumSize() - val w = mw * hudScale - val h = mh * hudScale - if (hud.renderedW != w || hud.renderedH != h) { - Snapshot.withMutableSnapshot { - hud.renderedW = w - hud.renderedH = h + try { + HudManager.updateIfDue(hud) + val hudScale = hud.effectiveScale + val (mw, mh) = hud.frameMinimumSize() + val w = mw * hudScale + val h = mh * hudScale + if (hud.renderedW != w || hud.renderedH != h) { + Snapshot.withMutableSnapshot { + hud.renderedW = w + hud.renderedH = h + } + } + //? >= 1.21.8 { + val pose = graphics.pose() + pose.pushMatrix() + try { + pose.translate(hud.x, hud.y) + if (hudScale != 1f) pose.scale(hudScale, hudScale) + hud.render(graphics) + } finally { + pose.popMatrix() + } + //? } else { + /*val pose = graphics.pose() + pose.pushPose() + try { + pose.translate(hud.x.toDouble(), hud.y.toDouble(), 0.0) + if (hudScale != 1f) pose.scale(hudScale, hudScale, 1f) + hud.render(graphics) + } finally { + pose.popPose() } + *///? } + } catch (e: Throwable) { + reportFailure(hud, e) } - //? >= 1.21.8 { - val pose = graphics.pose() - pose.pushMatrix() - pose.translate(hud.x, hud.y) - if (hudScale != 1f) pose.scale(hudScale, hudScale) - hud.render(graphics) - pose.popMatrix() - //? } else { - /*val pose = graphics.pose() - pose.pushPose() - pose.translate(hud.x.toDouble(), hud.y.toDouble(), 0.0) - if (hudScale != 1f) pose.scale(hudScale, hudScale, 1f) - hud.render(graphics) - pose.popPose() - *///? } } frame.clear() }