mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 10:58:15 -05:00
Update #51 - Protocol and FPS improvements, better workspace
This commit is contained in:
@ -56,6 +56,7 @@ class OpenGLObjects {
|
||||
private static int hashGen = 0;
|
||||
final WebGLVertexArray ptr;
|
||||
final int hash;
|
||||
int enabled;
|
||||
|
||||
VertexArrayGL(WebGLVertexArray ptr) {
|
||||
this.ptr = ptr;
|
||||
@ -71,6 +72,21 @@ class OpenGLObjects {
|
||||
PlatformOpenGL._wglDeleteVertexArrays(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBits() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBit(int bit) {
|
||||
enabled |= bit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetBit(int bit) {
|
||||
enabled &= ~bit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TextureGL implements ITextureGL {
|
||||
|
@ -242,7 +242,7 @@ public class PlatformAudio {
|
||||
}
|
||||
}
|
||||
|
||||
PlatformInput.clearEvenBuffers();
|
||||
PlatformInput.clearEventBuffers();
|
||||
|
||||
}
|
||||
|
||||
|
@ -1694,7 +1694,7 @@ public class PlatformInput {
|
||||
PlatformRuntime.logger.info("Waiting for user to select option on mobile press any key screen");
|
||||
}
|
||||
|
||||
public static void clearEvenBuffers() {
|
||||
public static void clearEventBuffers() {
|
||||
mouseEvents.clear();
|
||||
keyEvents.clear();
|
||||
touchEvents.clear();
|
||||
|
@ -19,6 +19,7 @@ package net.lax1dude.eaglercraft.v1_8.internal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.teavm.jso.webgl.WebGLShader;
|
||||
import org.teavm.jso.webgl.WebGLUniformLocation;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
@ -295,7 +296,17 @@ public class PlatformOpenGL {
|
||||
}
|
||||
|
||||
public static IShaderGL _wglCreateShader(int type) {
|
||||
return new OpenGLObjects.ShaderGL(ctx.createShader(type));
|
||||
WebGLShader shader = ctx.createShader(type);
|
||||
if(shader == null) {
|
||||
// Workaround for chrome not handling lost context correctly in shaderSource
|
||||
// "Failed to execute 'shaderSource' on 'WebGL2RenderingContext': parameter 1 is not of type 'WebGLShader'."
|
||||
if (PlatformInput.contextLost()) {
|
||||
throw new ContextLostError();
|
||||
} else {
|
||||
throw new Error("createShader returned null and the context is not lost");
|
||||
}
|
||||
}
|
||||
return new OpenGLObjects.ShaderGL(shader);
|
||||
}
|
||||
|
||||
public static IFramebufferGL _wglCreateFramebuffer() {
|
||||
|
@ -410,6 +410,11 @@ public class PlatformRuntime {
|
||||
|
||||
webgl = (WebGL2RenderingContext) webgl_;
|
||||
webglExperimental = experimental;
|
||||
|
||||
if (webgl.isContextLost()) {
|
||||
throw new ContextLostError();
|
||||
}
|
||||
|
||||
PlatformOpenGL.setCurrentContext(glesVer, webgl);
|
||||
|
||||
logger.info("OpenGL Version: {}", PlatformOpenGL._wglGetString(0x1F02));
|
||||
@ -1195,6 +1200,9 @@ public class PlatformRuntime {
|
||||
@JSBody(params = {}, script = "delete __isEaglerX188Running;")
|
||||
private static native void clearRunningFlag();
|
||||
|
||||
@JSBody(params = { "webgl" }, script = "var loseCtx = webgl.getExtension(\"WEBGL_lose_context\"); if (loseCtx) loseCtx.loseContext();")
|
||||
private static native void loseWebGLContext(WebGL2RenderingContext webgl);
|
||||
|
||||
static void enterBootMenu(boolean manual) {
|
||||
if(!getClientConfigAdapter().isAllowBootMenu()) {
|
||||
throw new IllegalStateException("Boot menu is disabled");
|
||||
@ -1207,8 +1215,9 @@ public class PlatformRuntime {
|
||||
removeEventHandlers();
|
||||
if(webgl != null) {
|
||||
EarlyLoadScreen.destroy();
|
||||
PlatformInput.clearEvenBuffers();
|
||||
PlatformInput.clearEventBuffers();
|
||||
WebGLBackBuffer.destroy();
|
||||
loseWebGLContext(webgl);
|
||||
}
|
||||
if(canvas != null) {
|
||||
canvas.delete();
|
||||
|
@ -146,7 +146,9 @@ public class PlatformVoiceClient {
|
||||
public final EaglercraftUUID peerId;
|
||||
public final JSObject peerConnection;
|
||||
public MediaStream rawStream;
|
||||
|
||||
|
||||
private MediaStreamAudioSourceNode audioNode = null;
|
||||
|
||||
private AnalyserNode analyser = null;
|
||||
private GainNode gain = null;
|
||||
private PannerNode panner = null;
|
||||
@ -372,50 +374,96 @@ public class PlatformVoiceClient {
|
||||
}
|
||||
}
|
||||
|
||||
public static void makePeerGlobal(EaglercraftUUID peerId) {
|
||||
VoicePeer peer = peerList.get(peerId);
|
||||
if (peer != null) {
|
||||
makePeerGlobalInternal(peer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void makePeerProximity(EaglercraftUUID peerId) {
|
||||
VoicePeer peer = peerList.get(peerId);
|
||||
if (peer != null) {
|
||||
makePeerProximityInternal(peer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void makePeerGlobalInternal(VoicePeer peer) {
|
||||
if (peer.audioNode == null) {
|
||||
return;
|
||||
}
|
||||
if (peer.panner != null) {
|
||||
if (peer.gain != null) {
|
||||
peer.panner.disconnect(peer.gain);
|
||||
}
|
||||
peer.audioNode.disconnect(peer.panner);
|
||||
peer.panner = null;
|
||||
} else if (peer.gain != null) {
|
||||
peer.audioNode.disconnect(peer.gain);
|
||||
}
|
||||
GainNode gain = PlatformAudio.audioctx.createGain();
|
||||
gain.getGain().setValue(VoiceClientController.getVoiceListenVolume());
|
||||
peer.audioNode.connect(gain);
|
||||
gain.connect(PlatformAudio.audioctx.getDestination());
|
||||
if(PlatformAudio.gameRecGain != null) {
|
||||
gain.connect(PlatformAudio.gameRecGain);
|
||||
}
|
||||
VoiceClientController.getVoiceListening().add(peer.peerId);
|
||||
peer.gain = gain;
|
||||
peer.recNode = gain;
|
||||
}
|
||||
|
||||
private static void makePeerProximityInternal(VoicePeer peer) {
|
||||
if (peer.audioNode == null) {
|
||||
return;
|
||||
}
|
||||
if (peer.panner != null) {
|
||||
if (peer.gain != null) {
|
||||
peer.panner.disconnect(peer.gain);
|
||||
}
|
||||
peer.audioNode.disconnect(peer.panner);
|
||||
peer.panner = null;
|
||||
} else if (peer.gain != null) {
|
||||
peer.audioNode.disconnect(peer.gain);
|
||||
}
|
||||
PannerNode panner = PlatformAudio.audioctx.createPanner();
|
||||
panner.setRolloffFactor(1f);
|
||||
panner.setDistanceModel("linear");
|
||||
panner.setPanningModel("HRTF");
|
||||
panner.setConeInnerAngle(360f);
|
||||
panner.setConeOuterAngle(0f);
|
||||
panner.setConeOuterGain(0f);
|
||||
panner.setOrientation(0f, 1f, 0f);
|
||||
panner.setPosition(0, 0, 0);
|
||||
float vol = VoiceClientController.getVoiceListenVolume();
|
||||
panner.setMaxDistance(vol * 2 * VoiceClientController.getVoiceProximity() + 0.1f);
|
||||
GainNode gain = PlatformAudio.audioctx.createGain();
|
||||
gain.getGain().setValue(vol);
|
||||
peer.audioNode.connect(gain);
|
||||
gain.connect(panner);
|
||||
panner.connect(PlatformAudio.audioctx.getDestination());
|
||||
if(PlatformAudio.gameRecGain != null) {
|
||||
panner.connect(PlatformAudio.gameRecGain);
|
||||
}
|
||||
VoiceClientController.getVoiceListening().add(peer.peerId);
|
||||
peer.panner = panner;
|
||||
peer.gain = gain;
|
||||
peer.recNode = panner;
|
||||
}
|
||||
|
||||
private static void handlePeerTrack(VoicePeer peer, MediaStream audioStream) {
|
||||
if (VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.NONE) return;
|
||||
MediaStreamAudioSourceNode audioNode = PlatformAudio.audioctx.createMediaStreamSource(audioStream);
|
||||
peer.audioNode = audioNode;
|
||||
AnalyserNode analyser = PlatformAudio.audioctx.createAnalyser();
|
||||
analyser.setSmoothingTimeConstant(0f);
|
||||
analyser.setFftSize(32);
|
||||
audioNode.connect(analyser);
|
||||
peer.analyser = analyser;
|
||||
if (VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.GLOBAL) {
|
||||
GainNode gain = PlatformAudio.audioctx.createGain();
|
||||
gain.getGain().setValue(VoiceClientController.getVoiceListenVolume());
|
||||
audioNode.connect(gain);
|
||||
gain.connect(PlatformAudio.audioctx.getDestination());
|
||||
if(PlatformAudio.gameRecGain != null) {
|
||||
gain.connect(PlatformAudio.gameRecGain);
|
||||
}
|
||||
VoiceClientController.getVoiceListening().add(peer.peerId);
|
||||
peer.analyser = analyser;
|
||||
peer.gain = gain;
|
||||
peer.recNode = gain;
|
||||
makePeerGlobalInternal(peer);
|
||||
} else if (VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) {
|
||||
PannerNode panner = PlatformAudio.audioctx.createPanner();
|
||||
panner.setRolloffFactor(1f);
|
||||
panner.setDistanceModel("linear");
|
||||
panner.setPanningModel("HRTF");
|
||||
panner.setConeInnerAngle(360f);
|
||||
panner.setConeOuterAngle(0f);
|
||||
panner.setConeOuterGain(0f);
|
||||
panner.setOrientation(0f, 1f, 0f);
|
||||
panner.setPosition(0, 0, 0);
|
||||
float vol = VoiceClientController.getVoiceListenVolume();
|
||||
panner.setMaxDistance(vol * 2 * VoiceClientController.getVoiceProximity() + 0.1f);
|
||||
GainNode gain = PlatformAudio.audioctx.createGain();
|
||||
gain.getGain().setValue(vol);
|
||||
audioNode.connect(gain);
|
||||
gain.connect(panner);
|
||||
panner.connect(PlatformAudio.audioctx.getDestination());
|
||||
if(PlatformAudio.gameRecGain != null) {
|
||||
panner.connect(PlatformAudio.gameRecGain);
|
||||
}
|
||||
VoiceClientController.getVoiceListening().add(peer.peerId);
|
||||
peer.analyser = analyser;
|
||||
peer.panner = panner;
|
||||
peer.gain = gain;
|
||||
peer.recNode = panner;
|
||||
makePeerProximityInternal(peer);
|
||||
}
|
||||
if (VoiceClientController.getVoiceMuted().contains(peer.peerId)) mutePeer(peer.peerId, true);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import org.teavm.jso.webgl.WebGLRenderingContext;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftVersion;
|
||||
import net.lax1dude.eaglercraft.v1_8.boot_menu.teavm.BootMenuEntryPoint;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.ContextLostError;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformIncompatibleException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
|
||||
@ -192,6 +193,13 @@ public class ClientMain {
|
||||
|
||||
try {
|
||||
EagRuntime.create();
|
||||
}catch(ContextLostError ex) {
|
||||
systemErr.println("ClientMain: [ERROR] webgl context lost during initialization!");
|
||||
try {
|
||||
showContextLostScreen(EagRuntime.getStackTrace(ex));
|
||||
}catch(Throwable t) {
|
||||
}
|
||||
return;
|
||||
}catch(PlatformIncompatibleException ex) {
|
||||
systemErr.println("ClientMain: [ERROR] this browser is incompatible with eaglercraftx!");
|
||||
systemErr.println("ClientMain: [ERROR] Reason: " + ex.getMessage());
|
||||
@ -221,6 +229,12 @@ public class ClientMain {
|
||||
|
||||
try {
|
||||
Main.appMain();
|
||||
}catch(ContextLostError ex) {
|
||||
systemErr.println("ClientMain: [ERROR] webgl context lost!");
|
||||
try {
|
||||
showContextLostScreen(EagRuntime.getStackTrace(ex));
|
||||
}catch(Throwable t) {
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
systemErr.println("ClientMain: [ERROR] unhandled exception caused main thread to exit");
|
||||
EagRuntime.debugPrintStackTraceToSTDERR(t);
|
||||
@ -619,6 +633,52 @@ public class ClientMain {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showContextLostScreen(String t) {
|
||||
if(!isCrashed) {
|
||||
isCrashed = true;
|
||||
|
||||
HTMLDocument doc = Window.current().getDocument();
|
||||
HTMLElement el;
|
||||
if(PlatformRuntime.parent != null) {
|
||||
el = PlatformRuntime.parent;
|
||||
}else {
|
||||
if(configRootElement == null) {
|
||||
configRootElement = doc.getElementById(configRootElementId);
|
||||
}
|
||||
el = configRootElement;
|
||||
}
|
||||
|
||||
if(el == null) {
|
||||
Window.alert("WebGL context lost!");
|
||||
System.err.println("WebGL context lost: " + t);
|
||||
return;
|
||||
}
|
||||
|
||||
String s = el.getAttribute("style");
|
||||
el.setAttribute("style", (s == null ? "" : s) + "position:relative;");
|
||||
HTMLElement img = doc.createElement("img");
|
||||
HTMLElement div = doc.createElement("div");
|
||||
img.setAttribute("style", "z-index:100;position:absolute;top:10px;left:calc(50% - 151px);");
|
||||
img.setAttribute("src", crashImageWrapper());
|
||||
div.setAttribute("style", "z-index:100;position:absolute;top:135px;left:10%;right:10%;bottom:50px;background-color:white;border:1px solid #cccccc;overflow-x:hidden;overflow-y:scroll;font:18px sans-serif;padding:40px;");
|
||||
div.getClassList().add("_eaglercraftX_context_lost_element");
|
||||
el.appendChild(img);
|
||||
el.appendChild(div);
|
||||
div.setInnerHTML("<h2><svg style=\"vertical-align:middle;margin:0px 16px 8px 8px;\" xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 48 48\" fill=\"none\"><path stroke=\"#000000\" stroke-width=\"3\" stroke-linecap=\"square\" d=\"M1.5 8.5v34h45v-28m-3-3h-10v-3m-3-3h-10m15 6h-18v-3m-3-3h-10\"/><path stroke=\"#000000\" stroke-width=\"2\" stroke-linecap=\"square\" d=\"M12 21h0m0 4h0m4 0h0m0-4h0m-2 2h0m20-2h0m0 4h0m4 0h0m0-4h0m-2 2h0\"/><path stroke=\"#000000\" stroke-width=\"2\" stroke-linecap=\"square\" d=\"M20 30h0 m2 2h0 m2 2h0 m2 2h0 m2 -2h0 m2 -2h0 m2 -2h0\"/></svg> + WebGL context lost!</h2>"
|
||||
+ "<div style=\"margin-left:40px;\">"
|
||||
+ "<p style=\"font-size:1.2em;\">Your browser has forcibly released all of the resources "
|
||||
+ "allocated by the game's 3D rendering context. EaglercraftX cannot continue, please refresh "
|
||||
+ "the page to restart the game.</p>"
|
||||
+ "<p style=\"font-size:1.2em;\">This is not a bug, it is usually caused by the browser "
|
||||
+ "deciding it no longer has sufficient resources to continue rendering this page. If it "
|
||||
+ "happens again, try closing your other browser tabs and windows.</p>"
|
||||
+ "<p style=\"overflow-wrap:break-word;white-space:pre-wrap;font:0.75em monospace;margin-top:1.5em;\" id=\"_eaglercraftX_contextLostTrace\"></p>"
|
||||
+ "</div>");
|
||||
|
||||
div.querySelector("#_eaglercraftX_contextLostTrace").appendChild(doc.createTextNode(t));
|
||||
}
|
||||
}
|
||||
|
||||
public static HTMLElement integratedServerCrashPanel = null;
|
||||
public static boolean integratedServerCrashPanelShowing = false;
|
||||
|
||||
|
@ -248,7 +248,7 @@ public class WebGLBackBuffer {
|
||||
}
|
||||
GlStateManager.eagPopStateForGLES2BlitHack();
|
||||
}else {
|
||||
EaglercraftGPU.clearCurrentBinding(EaglercraftGPU.CLEAR_BINDING_TEXTURE0 | EaglercraftGPU.CLEAR_BINDING_ACTIVE_TEXTURE | EaglercraftGPU.CLEAR_BINDING_SHADER_PROGRAM | EaglercraftGPU.CLEAR_BINDING_BUFFER_ARRAY);
|
||||
EaglercraftGPU.clearCurrentBinding(EaglercraftGPU.CLEAR_BINDING_TEXTURE0 | EaglercraftGPU.CLEAR_BINDING_ACTIVE_TEXTURE | EaglercraftGPU.CLEAR_BINDING_SHADER_PROGRAM | EaglercraftGPU.CLEAR_BINDING_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
ctx.bindFramebuffer(_GL_FRAMEBUFFER, framebuffer);
|
||||
|
Reference in New Issue
Block a user