diff --git a/lwjgl-rundir/resources/lang/en_US.lang b/lwjgl-rundir/resources/lang/en_US.lang index 070b835..0ee135d 100644 --- a/lwjgl-rundir/resources/lang/en_US.lang +++ b/lwjgl-rundir/resources/lang/en_US.lang @@ -492,6 +492,18 @@ performance.max=Max FPS performance.balanced=Balanced performance.powersaver=Power saver +options.vsyncWarning.title=Issues Detected +options.vsyncWarning.0=Some of your video settings may be causing +options.vsyncWarning.1=the game to lag excessively +options.vsyncWarning.2=VSync is disabled, some browsers require +options.vsyncWarning.3=VSync to be enabled to hint when the +options.vsyncWarning.4=framebuffer has updated. If the game feels +options.vsyncWarning.5=significantly slower than is indicated by +options.vsyncWarning.6=the FPS counter, you should enable VSync. +options.vsyncWarning.fixSettings=Fix Settings +options.vsyncWarning.continueAnyway=Continue Anyway +options.vsyncWarning.doNotShowAgain=Do Not Show Again + controls.title=Controls key.forward=Forward diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java index bd2d085..224cfef 100644 --- a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java @@ -2,6 +2,7 @@ package net.lax1dude.eaglercraft.sp; import java.io.IOException; +import net.lax1dude.eaglercraft.sp.ipc.IPCPacket14StringList; import net.minecraft.server.MinecraftServer; import net.minecraft.src.EnumGameType; import net.minecraft.src.ILogAgent; @@ -15,6 +16,9 @@ public class EAGMinecraftServer extends MinecraftServer { protected WorkerListenThread listenThreadImpl; protected WorldSettings newWorldSettings; protected boolean paused; + private int tpsCounter = 0; + private int tpsMeasure = 0; + private long tpsTimer = 0l; public EAGMinecraftServer(String world, String owner, WorldSettings currentWorldSettings) { super(world); @@ -36,12 +40,21 @@ public class EAGMinecraftServer extends MinecraftServer { } public void mainLoop() { + long ctm = SysUtil.steadyTimeMillis(); + + long elapsed = ctm - tpsTimer; + if(elapsed >= 1000l) { + tpsTimer = ctm; + tpsMeasure = tpsCounter; + IntegratedServer.sendIPCPacket(new IPCPacket14StringList(IPCPacket14StringList.SERVER_TPS, getTPSAndChunkBuffer(tpsMeasure))); + tpsCounter = 0; + } + if(paused && this.playersOnline.size() <= 1) { - lastTick = SysUtil.steadyTimeMillis(); + lastTick = ctm; return; } - long ctm = SysUtil.steadyTimeMillis(); long delta = ctm - lastTick; if (delta > 2000L && ctm - this.timeOfLastWarning >= 15000L) { @@ -57,12 +70,14 @@ public class EAGMinecraftServer extends MinecraftServer { if (this.worldServers[0].areAllPlayersAsleep()) { this.tick(); + ++tpsCounter; lastTick = SysUtil.steadyTimeMillis(); } else { - if (delta >= 50l) { + if (delta > 50l) { delta -= 50L; lastTick += 50l; this.tick(); + ++tpsCounter; } } diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SysUtil.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SysUtil.java index d56cc28..09c55bb 100644 --- a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SysUtil.java +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SysUtil.java @@ -52,7 +52,6 @@ public class SysUtil { private static boolean hasCheckedImmediateContinue = false; private static MessageChannel immediateContinueChannel = null; private static Runnable currentContinueHack = null; - private static final Object immediateContLock = new Object(); private static final JSString emptyJSString = JSString.valueOf(""); public static void immediateContinue() { @@ -71,20 +70,18 @@ public class SysUtil { private static native void immediateContinueTeaVM(); private static void immediateContinueTeaVM(final AsyncCallback cb) { - synchronized(immediateContLock) { - if(currentContinueHack != null) { - cb.error(new IllegalStateException("Worker thread is already waiting for an immediate continue callback!")); - return; - } - currentContinueHack = () -> { - cb.complete(null); - }; - try { - immediateContinueChannel.getPort2().postMessage(emptyJSString); - }catch(Throwable t) { - System.err.println("Caught error posting immediate continue, using setTimeout instead"); - Window.setTimeout(() -> cb.complete(null), 0); - } + if(currentContinueHack != null) { + cb.error(new IllegalStateException("Worker thread is already waiting for an immediate continue callback!")); + return; + } + currentContinueHack = () -> { + cb.complete(null); + }; + try { + immediateContinueChannel.getPort2().postMessage(emptyJSString); + }catch(Throwable t) { + System.err.println("Caught error posting immediate continue, using setTimeout instead"); + Window.setTimeout(() -> cb.complete(null), 0); } } @@ -99,11 +96,8 @@ public class SysUtil { immediateContinueChannel.getPort1().addEventListener("message", new EventListener() { @Override public void handleEvent(MessageEvent evt) { - Runnable toRun; - synchronized(immediateContLock) { - toRun = currentContinueHack; - currentContinueHack = null; - } + Runnable toRun = currentContinueHack; + currentContinueHack = null; if(toRun != null) { toRun.run(); } diff --git a/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java b/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java index bc21910..c629fb3 100644 --- a/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java @@ -126,10 +126,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable { protected boolean startProfiling; protected boolean field_104057_T = false; - private int tpsCounter = 0; - private int tpsMeasure = 0; - private long tpsTimer = 0l; - public MinecraftServer(String folder) { mcServer = this; this.folderName = folder; @@ -455,19 +451,9 @@ public abstract class MinecraftServer implements ICommandSender, Runnable { this.lastReceivedSize = Packet.receivedSize; this.theProfiler.endSection(); this.theProfiler.endSection(); - - ++tpsCounter; - long millis = SysUtil.steadyTimeMillis(); - long elapsed = millis - tpsTimer; - if(elapsed >= 1000l) { - tpsTimer = millis; - tpsMeasure = (int)(tpsCounter * 1000l / elapsed); - IntegratedServer.sendIPCPacket(new IPCPacket14StringList(IPCPacket14StringList.SERVER_TPS, getTPSAndChunkBuffer())); - tpsCounter = 0; - } } - public List getTPSAndChunkBuffer() { + public List getTPSAndChunkBuffer(int tpsCounter) { ArrayList strs = new ArrayList(); strs.add("Ticks/Second: " + tpsCounter + "/20"); diff --git a/src/main/java/net/lax1dude/eaglercraft/GuiScreenVSyncWarning.java b/src/main/java/net/lax1dude/eaglercraft/GuiScreenVSyncWarning.java new file mode 100644 index 0000000..2526e1b --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GuiScreenVSyncWarning.java @@ -0,0 +1,78 @@ +package net.lax1dude.eaglercraft; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.src.EnumChatFormatting; +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.StatCollector; + +public class GuiScreenVSyncWarning extends GuiScreen { + + private final GuiScreen cont; + private final List messages = new ArrayList<>(); + private int top = 0; + + public GuiScreenVSyncWarning(GuiScreen cont) { + this.cont = cont; + } + + public void initGui() { + messages.clear(); + messages.add(EnumChatFormatting.RED + StatCollector.translateToLocal("options.vsyncWarning.title")); + messages.add(null); + messages.add(EnumChatFormatting.GRAY + StatCollector.translateToLocal("options.vsyncWarning.0")); + messages.add(EnumChatFormatting.GRAY + StatCollector.translateToLocal("options.vsyncWarning.1")); + messages.add(null); + messages.add(StatCollector.translateToLocal("options.vsyncWarning.2")); + messages.add(StatCollector.translateToLocal("options.vsyncWarning.3")); + messages.add(StatCollector.translateToLocal("options.vsyncWarning.4")); + messages.add(StatCollector.translateToLocal("options.vsyncWarning.5")); + messages.add(StatCollector.translateToLocal("options.vsyncWarning.6")); + int j = 0; + for(int i = 0, l = messages.size(); i < l; ++i) { + if(messages.get(i) != null) { + j += 9; + }else { + j += 5; + } + } + top = this.height / 6 + j / -12; + j += top; + buttonList.clear(); + buttonList.add(new GuiButton(0, this.width / 2 - 100, j + 16, StatCollector.translateToLocal("options.vsyncWarning.fixSettings"))); + buttonList.add(new GuiButton(1, this.width / 2 - 100, j + 40, StatCollector.translateToLocal("options.vsyncWarning.continueAnyway"))); + buttonList.add(new GuiButton(2, this.width / 2 - 100, j + 64, StatCollector.translateToLocal("options.vsyncWarning.doNotShowAgain"))); + } + + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + int j = 0; + for(int i = 0, l = messages.size(); i < l; ++i) { + String str = messages.get(i); + if(str != null) { + this.drawCenteredString(fontRenderer, str, this.width / 2, top + j, 16777215); + j += 9; + }else { + j += 5; + } + } + super.drawScreen(par1, par2, par3); + } + + protected void actionPerformed(GuiButton par1GuiButton) { + if(par1GuiButton.id == 0) { + mc.gameSettings.enableVsync = true; + mc.gameSettings.saveOptions(); + mc.displayGuiScreen(cont); + }else if(par1GuiButton.id == 1) { + mc.displayGuiScreen(cont); + }else if(par1GuiButton.id == 2) { + mc.gameSettings.hideVsyncWarning = true; + mc.gameSettings.saveOptions(); + mc.displayGuiScreen(cont); + } + } + +} diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java index 28a8373..275ea74 100644 --- a/src/main/java/net/minecraft/client/Minecraft.java +++ b/src/main/java/net/minecraft/client/Minecraft.java @@ -13,6 +13,7 @@ import net.lax1dude.eaglercraft.EaglerProfile; import net.lax1dude.eaglercraft.GuiScreenEditProfile; import net.lax1dude.eaglercraft.GuiScreenSingleplayerConnecting; import net.lax1dude.eaglercraft.GuiScreenSingleplayerLoading; +import net.lax1dude.eaglercraft.GuiScreenVSyncWarning; import net.lax1dude.eaglercraft.GuiVoiceOverlay; import net.lax1dude.eaglercraft.IntegratedServer; import net.lax1dude.eaglercraft.IntegratedServerLAN; @@ -353,6 +354,10 @@ public class Minecraft implements Runnable { scr = new GuiScreenEditProfile(new GuiMainMenu()); } + if(!gameSettings.enableVsync && !gameSettings.hideVsyncWarning) { + scr = new GuiScreenVSyncWarning(scr); + } + displayGuiScreen(scr); this.loadingScreen = new LoadingScreenRenderer(this); @@ -1102,8 +1107,12 @@ public class Minecraft implements Runnable { } public void updateDisplay() { - int i = this.func_90020_K(); - EaglerAdapter.updateDisplay(i > 0 ? EntityRenderer.performanceToFps(i) : 0, false); + if(gameSettings.enableVsync) { + EaglerAdapter.updateDisplay(0, true); + }else { + int i = this.func_90020_K(); + EaglerAdapter.updateDisplay(i > 0 ? EntityRenderer.performanceToFps(i) : 0, false); + } } private boolean wasPaused = false; diff --git a/src/main/java/net/minecraft/src/EnumOptions.java b/src/main/java/net/minecraft/src/EnumOptions.java index abfe2b3..ffd210c 100644 --- a/src/main/java/net/minecraft/src/EnumOptions.java +++ b/src/main/java/net/minecraft/src/EnumOptions.java @@ -8,7 +8,8 @@ public enum EnumOptions { CHAT_VISIBILITY("options.chat.visibility", false, false), CHAT_COLOR("options.chat.color", false, true), CHAT_LINKS("options.chat.links", false, true), CHAT_OPACITY("options.chat.opacity", true, false), CHAT_LINKS_PROMPT("options.chat.links.prompt", false, true), USE_SERVER_TEXTURES("options.serverTextures", false, true), SNOOPER_ENABLED("options.snooper", false, true), USE_FULLSCREEN("options.fullscreen", false, true), ENABLE_FOG("options.fog", false, true), SHOW_CAPE("options.showCape", false, true), ANTIALIASING("options.framebufferAntialias", false, false), CHAT_SCALE("options.chat.scale", true, false), CHAT_WIDTH("options.chat.width", true, false), - CHAT_HEIGHT_FOCUSED("options.chat.height.focused", true, false), CHAT_HEIGHT_UNFOCUSED("options.chat.height.unfocused", true, false), CHUNK_UPDATES("options.chunkUpdates", false, false), ADDERALL("options.adderall", false, true); + CHAT_HEIGHT_FOCUSED("options.chat.height.focused", true, false), CHAT_HEIGHT_UNFOCUSED("options.chat.height.unfocused", true, false), CHUNK_UPDATES("options.chunkUpdates", false, false), ADDERALL("options.adderall", false, true), + VSYNC("options.vsync", false, true); private final boolean enumFloat; private final boolean enumBoolean; diff --git a/src/main/java/net/minecraft/src/EnumOptionsHelper.java b/src/main/java/net/minecraft/src/EnumOptionsHelper.java index 0aa9f73..cc71b29 100644 --- a/src/main/java/net/minecraft/src/EnumOptionsHelper.java +++ b/src/main/java/net/minecraft/src/EnumOptionsHelper.java @@ -22,6 +22,12 @@ class EnumOptionsHelper { ; } + try { + enumOptionsMappingHelperArray[EnumOptions.VSYNC.ordinal()] = 4; + } catch (NoSuchFieldError var10) { + ; + } + try { enumOptionsMappingHelperArray[EnumOptions.RENDER_CLOUDS.ordinal()] = 5; } catch (NoSuchFieldError var10) { diff --git a/src/main/java/net/minecraft/src/GameSettings.java b/src/main/java/net/minecraft/src/GameSettings.java index 54b4c60..f6bc954 100644 --- a/src/main/java/net/minecraft/src/GameSettings.java +++ b/src/main/java/net/minecraft/src/GameSettings.java @@ -49,6 +49,7 @@ public class GameSettings { public boolean snooperEnabled = false; public boolean fullScreen = false; public boolean enableVsync = true; + public boolean hideVsyncWarning = false; public boolean hideServerAddress = false; /** @@ -367,6 +368,10 @@ public class GameSettings { this.mc.sndManager.stopAllSounds(); } + if (par1EnumOptions == EnumOptions.VSYNC) { + this.enableVsync = !this.enableVsync; + } + this.saveOptions(); } @@ -394,7 +399,7 @@ public class GameSettings { return this.anaglyph; case 4: - return this.advancedOpengl; + return this.enableVsync; case 5: return this.clouds; @@ -546,6 +551,8 @@ public class GameSettings { if(yee.hasKey("relayTimeout")) relayTimeout = yee.getByte("relayTimeout"); if(yee.hasKey("adderall")) adderall = yee.getBoolean("adderall"); if(yee.hasKey("skin")) skin = yee.getString("skin"); + if(yee.hasKey("enableVsync")) enableVsync = yee.getBoolean("enableVsync"); + if(yee.hasKey("hideVsyncWarning")) hideVsyncWarning = yee.getBoolean("hideVsyncWarning"); if(voiceListenRadius < 5) voiceListenRadius = 5; else if(voiceListenRadius > 22) voiceListenRadius = 22; @@ -628,6 +635,8 @@ public class GameSettings { yee.setByte("relayTimeout", (byte)relayTimeout); yee.setBoolean("adderall", adderall); yee.setString("skin", skin); + yee.setBoolean("enableVsync", enableVsync); + yee.setBoolean("hideVsyncWarning", hideVsyncWarning); for (int var4 = 0; var4 < this.keyBindings.length; ++var4) { yee.setInteger(keyBindings[var4].keyDescription, keyBindings[var4].keyCode); diff --git a/src/main/java/net/minecraft/src/GuiVideoSettings.java b/src/main/java/net/minecraft/src/GuiVideoSettings.java index e9e00a2..07f2349 100644 --- a/src/main/java/net/minecraft/src/GuiVideoSettings.java +++ b/src/main/java/net/minecraft/src/GuiVideoSettings.java @@ -1,5 +1,7 @@ package net.minecraft.src; +import net.lax1dude.eaglercraft.GuiScreenVSyncWarning; + public class GuiVideoSettings extends GuiScreen { private GuiScreen parentGuiScreen; @@ -9,15 +11,11 @@ public class GuiVideoSettings extends GuiScreen { /** GUI game settings */ private GameSettings guiGameSettings; - /** - * True if the system is 64-bit (using a simple indexOf test on a system - * property) - */ - private boolean is64bit = false; - /** An array of all of EnumOption's video options. */ - private static EnumOptions[] videoOptions = new EnumOptions[] { EnumOptions.GRAPHICS, EnumOptions.RENDER_DISTANCE, EnumOptions.AMBIENT_OCCLUSION, EnumOptions.FRAMERATE_LIMIT, EnumOptions.ANAGLYPH, EnumOptions.VIEW_BOBBING, - EnumOptions.GUI_SCALE, EnumOptions.GAMMA, EnumOptions.RENDER_CLOUDS, EnumOptions.ENABLE_FOG, EnumOptions.PARTICLES, EnumOptions.CHUNK_UPDATES, EnumOptions.ADDERALL }; + private static EnumOptions[] videoOptions = new EnumOptions[] { EnumOptions.GRAPHICS, EnumOptions.RENDER_DISTANCE, + EnumOptions.AMBIENT_OCCLUSION, EnumOptions.FRAMERATE_LIMIT, EnumOptions.VSYNC, EnumOptions.ANAGLYPH, + EnumOptions.VIEW_BOBBING, EnumOptions.GUI_SCALE, EnumOptions.GAMMA, EnumOptions.RENDER_CLOUDS, + EnumOptions.ENABLE_FOG, EnumOptions.PARTICLES, EnumOptions.CHUNK_UPDATES, EnumOptions.ADDERALL }; public GuiVideoSettings(GuiScreen par1GuiScreen, GameSettings par2GameSettings) { this.parentGuiScreen = par1GuiScreen; @@ -32,7 +30,6 @@ public class GuiVideoSettings extends GuiScreen { this.screenTitle = var1.translateKey("options.videoTitle"); this.buttonList.clear(); this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 178, var1.translateKey("gui.done"))); - this.is64bit = true; /* String[] var2 = new String[] { "sun.arch.data.model", "com.ibm.vm.bitmode", "os.arch" }; String[] var3 = var2; @@ -83,7 +80,11 @@ public class GuiVideoSettings extends GuiScreen { if (par1GuiButton.id == 200) { this.mc.gameSettings.saveOptions(); - this.mc.displayGuiScreen(this.parentGuiScreen); + if(!this.mc.gameSettings.enableVsync && !this.mc.gameSettings.hideVsyncWarning) { + this.mc.displayGuiScreen(new GuiScreenVSyncWarning(this.parentGuiScreen)); + }else { + this.mc.displayGuiScreen(this.parentGuiScreen); + } } if (this.guiGameSettings.guiScale != var2) { @@ -101,13 +102,7 @@ public class GuiVideoSettings extends GuiScreen { */ public void drawScreen(int par1, int par2, float par3) { this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, this.is64bit ? 20 : 5, 16777215); - - if (!this.is64bit && this.guiGameSettings.renderDistance == 0) { - this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("options.farWarning1"), this.width / 2, this.height / 6 + 144 + 1, 11468800); - this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("options.farWarning2"), this.width / 2, this.height / 6 + 144 + 13, 11468800); - } - + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 20, 16777215); super.drawScreen(par1, par2, par3); } }