From 33c94310280edc60e9072ce0a7e1d914acea545e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E8=91=89=20Scarlet?= <93977077+MukjepScarlet@users.noreply.github.com> Date: Wed, 31 Dec 2025 16:38:57 +0800 Subject: [PATCH 1/5] fix(NESEmulator): update to 1.21.11 --- examples/nes_emulator/main.js | 47 ++++++++++++++++------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/examples/nes_emulator/main.js b/examples/nes_emulator/main.js index 8274963..0dd0f48 100644 --- a/examples/nes_emulator/main.js +++ b/examples/nes_emulator/main.js @@ -5,11 +5,10 @@ const script = registerScript({ }); const File = Java.type("java.io.File"); -const Files = Java.type("java.nio.file.Files"); -const RenderShortcutsKt = Java.type("net.ccbluex.liquidbounce.render.RenderShortcutsKt"); -const NativeImageBackedTexture = Java.type("net.minecraft.client.texture.NativeImageBackedTexture"); -const RenderSystem = Java.type("com.mojang.blaze3d.systems.RenderSystem"); -const Vec3d = Java.type("net.minecraft.util.math.Vec3d"); +const RenderPipelines = Java.type("net.minecraft.client.renderer.RenderPipelines"); +const Render2DKt = Java.type("net.ccbluex.liquidbounce.render.Render2DKt") +const TextureSetup = Java.type("net.minecraft.client.gui.render.TextureSetup"); +const DynamicTexture = Java.type("net.minecraft.client.renderer.texture.DynamicTexture"); const FileUtils = Java.type("org.apache.commons.io.FileUtils"); const StandardCharsets = Java.type("java.nio.charset.StandardCharsets"); const Thread = Java.type("java.lang.Thread"); @@ -26,12 +25,12 @@ function readRom(name) { } function getInstalledRoms() { - return ["None", ...new File(ROMS_BASE_PATH).listFiles().map(f => f.getName())]; + return ["None", ...(new File(ROMS_BASE_PATH).listFiles() ?? []).map(f => f.getName())]; } const installedRoms = getInstalledRoms(); -const texture = new NativeImageBackedTexture(SCREEN_WIDTH, SCREEN_HEIGHT, false); +const texture = new DynamicTexture("NESEmulator Texture", SCREEN_WIDTH, SCREEN_HEIGHT, false); script.registerModule({ name: "NESEmulator", @@ -147,7 +146,7 @@ script.registerModule({ nes.loadROM(readRom(mod.settings.rom.value)); - UnsafeThread.run(() => { + AsyncUtil.launch(() => { while (runEmulator) { nes.frame(); Thread.sleep((1000 / targetFramerate) | 0); @@ -163,7 +162,7 @@ script.registerModule({ const key = e.getKey(); for (const k of controller) { - if (k.setting.value.getTranslationKey() === key.getTranslationKey()) { + if (k.setting.value.getName() === key.getName()) { if (e.getAction() === 1 || e.getAction() === 2) { nes.buttonDown(1, k.emulatorKey); } else { @@ -176,24 +175,20 @@ script.registerModule({ mod.on("overlayRender", e => { const context = e.getContext(); - const x = context.getScaledWindowWidth() / 2 - SCREEN_WIDTH / 2; - const y = context.getScaledWindowHeight() / 2 - SCREEN_HEIGHT / 2; + const x = context.guiWidth() / 2 - SCREEN_WIDTH / 2; + const y = context.guiHeight() / 2 - SCREEN_HEIGHT / 2; - RenderShortcutsKt.renderEnvironmentForGUI(context.getMatrices(), renderEnvironment => { - texture.bindTexture(); - - if (dirty) { - texture.upload(); - dirty = false; - } - - RenderSystem.bindTexture(texture.getGlId()); - RenderSystem.setShaderTexture(0, texture.getGlId()); - - RenderShortcutsKt.drawTextureQuad(renderEnvironment, new Vec3d(x, y, 0), new Vec3d(x + SCREEN_WIDTH, y + SCREEN_HEIGHT, 0)); + if (dirty) { + texture.upload(); + dirty = false; + } - RenderSystem.setShaderTexture(0, 0); - }); + Render2DKt.drawBlitOnCurrentLayer( + context, + TextureSetup.singleTexture(texture.getTextureView(), texture.getSampler()), + x, y, + x + SCREEN_WIDTH, y + SCREEN_HEIGHT, + 0, 0, 1, 1, -1, RenderPipelines.GUI_TEXTURED, + ) }); }); - From e8a8dc01f268820f2b89d2a78037548ba903506e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E8=91=89=20Scarlet?= <93977077+MukjepScarlet@users.noreply.github.com> Date: Wed, 31 Dec 2025 16:51:54 +0800 Subject: [PATCH 2/5] Make x/y always floored --- examples/nes_emulator/main.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/nes_emulator/main.js b/examples/nes_emulator/main.js index 0dd0f48..17e59c4 100644 --- a/examples/nes_emulator/main.js +++ b/examples/nes_emulator/main.js @@ -174,9 +174,8 @@ script.registerModule({ mod.on("overlayRender", e => { const context = e.getContext(); - - const x = context.guiWidth() / 2 - SCREEN_WIDTH / 2; - const y = context.guiHeight() / 2 - SCREEN_HEIGHT / 2; + const x = ~~(context.guiWidth() / 2 - SCREEN_WIDTH / 2); + const y = ~~(context.guiHeight() / 2 - SCREEN_HEIGHT / 2); if (dirty) { texture.upload(); From 79fd06f738c0248a99fc39606a4ca44469f6bb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E8=91=89=20Scarlet?= <93977077+MukjepScarlet@users.noreply.github.com> Date: Sat, 3 Jan 2026 02:23:18 +0800 Subject: [PATCH 3/5] fix --- examples/nes_emulator/main.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/nes_emulator/main.js b/examples/nes_emulator/main.js index 17e59c4..98d66eb 100644 --- a/examples/nes_emulator/main.js +++ b/examples/nes_emulator/main.js @@ -30,7 +30,15 @@ function getInstalledRoms() { const installedRoms = getInstalledRoms(); -const texture = new DynamicTexture("NESEmulator Texture", SCREEN_WIDTH, SCREEN_HEIGHT, false); +let texture = null; + +script.on("enable", () => { + texture = new DynamicTexture("NESEmulator Texture", SCREEN_WIDTH, SCREEN_HEIGHT, false); +}); +script.on("disable", () => { + texture?.close(); + texture = null; +}); script.registerModule({ name: "NESEmulator", @@ -133,11 +141,13 @@ script.registerModule({ runEmulator = true; nes = new NES({ onFrame: frameBuffer => { + if (!texture) return; + for (let i = 0; i < frameBuffer.length; i++) { const x = i % SCREEN_WIDTH; const y = (i / SCREEN_WIDTH) | 0; - texture.getImage().setColor(x, y, frameBuffer[i] | (255 << 24)); + texture.getPixels().setPixelABGR(x, y, frameBuffer[i] | (255 << 24)); } dirty = true; @@ -156,6 +166,7 @@ script.registerModule({ mod.on("disable", () => { runEmulator = false; + nes = null; }); mod.on("key", e => { @@ -164,15 +175,17 @@ script.registerModule({ for (const k of controller) { if (k.setting.value.getName() === key.getName()) { if (e.getAction() === 1 || e.getAction() === 2) { - nes.buttonDown(1, k.emulatorKey); + nes?.buttonDown(1, k.emulatorKey); } else { - nes.buttonUp(1, k.emulatorKey); + nes?.buttonUp(1, k.emulatorKey); } } } }); mod.on("overlayRender", e => { + if (!texture) return; + const context = e.getContext(); const x = ~~(context.guiWidth() / 2 - SCREEN_WIDTH / 2); const y = ~~(context.guiHeight() / 2 - SCREEN_HEIGHT / 2); @@ -182,7 +195,7 @@ script.registerModule({ dirty = false; } - Render2DKt.drawBlitOnCurrentLayer( + Render2DKt.drawTexQuad( context, TextureSetup.singleTexture(texture.getTextureView(), texture.getSampler()), x, y, From 008e5e7fbe03a89d7628540e8db676a6ba6b4da6 Mon Sep 17 00:00:00 2001 From: Senk Ju <18741573+SenkJu@users.noreply.github.com> Date: Fri, 2 Jan 2026 19:45:07 +0100 Subject: [PATCH 4/5] add scale setting --- examples/nes_emulator/main.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/nes_emulator/main.js b/examples/nes_emulator/main.js index 98d66eb..51e557c 100644 --- a/examples/nes_emulator/main.js +++ b/examples/nes_emulator/main.js @@ -55,6 +55,11 @@ script.registerModule({ choices: ["NTSC", "PAL"], default: "NTSC" }), + scale: Setting.float({ + name: "Scale", + default: 1, + range: [1, 5] + }), buttonA: Setting.key({ name: "ButtonA", default: "key.keyboard.z" @@ -187,8 +192,8 @@ script.registerModule({ if (!texture) return; const context = e.getContext(); - const x = ~~(context.guiWidth() / 2 - SCREEN_WIDTH / 2); - const y = ~~(context.guiHeight() / 2 - SCREEN_HEIGHT / 2); + const x = ~~(context.guiWidth() / 2 - Math.floor(SCREEN_WIDTH * mod.settings.scale.value) / 2); + const y = ~~(context.guiHeight() / 2 - Math.floor(SCREEN_HEIGHT * mod.settings.scale.value) / 2); if (dirty) { texture.upload(); @@ -199,8 +204,8 @@ script.registerModule({ context, TextureSetup.singleTexture(texture.getTextureView(), texture.getSampler()), x, y, - x + SCREEN_WIDTH, y + SCREEN_HEIGHT, - 0, 0, 1, 1, -1, RenderPipelines.GUI_TEXTURED, + x + Math.floor(SCREEN_WIDTH * mod.settings.scale.value) , y + Math.floor(SCREEN_HEIGHT * mod.settings.scale.value), + 0, 0, 1, 1, -1, RenderPipelines.GUI_TEXTURED ) }); }); From ae649beb3972c2c6ee6331aee3a718516be677e0 Mon Sep 17 00:00:00 2001 From: Senk Ju <18741573+SenkJu@users.noreply.github.com> Date: Fri, 2 Jan 2026 19:56:41 +0100 Subject: [PATCH 5/5] dont use ints when not necessary --- examples/nes_emulator/main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/nes_emulator/main.js b/examples/nes_emulator/main.js index 51e557c..0b5f49e 100644 --- a/examples/nes_emulator/main.js +++ b/examples/nes_emulator/main.js @@ -192,8 +192,8 @@ script.registerModule({ if (!texture) return; const context = e.getContext(); - const x = ~~(context.guiWidth() / 2 - Math.floor(SCREEN_WIDTH * mod.settings.scale.value) / 2); - const y = ~~(context.guiHeight() / 2 - Math.floor(SCREEN_HEIGHT * mod.settings.scale.value) / 2); + const x = Primitives.float(context.guiWidth() / 2 - SCREEN_WIDTH * mod.settings.scale.value / 2); + const y = Primitives.float(context.guiHeight() / 2 - SCREEN_HEIGHT * mod.settings.scale.value / 2); if (dirty) { texture.upload(); @@ -204,7 +204,7 @@ script.registerModule({ context, TextureSetup.singleTexture(texture.getTextureView(), texture.getSampler()), x, y, - x + Math.floor(SCREEN_WIDTH * mod.settings.scale.value) , y + Math.floor(SCREEN_HEIGHT * mod.settings.scale.value), + Primitives.float(x + SCREEN_WIDTH * mod.settings.scale.value), Primitives.float(y + SCREEN_HEIGHT * mod.settings.scale.value), 0, 0, 1, 1, -1, RenderPipelines.GUI_TEXTURED ) });