Update #53 - Improved FPS, reduced WebGL context loss crashes

This commit is contained in:
lax1dude
2025-07-06 12:31:55 -07:00
parent f3281c037f
commit 332a7bb11f
53 changed files with 568 additions and 383 deletions

View File

@ -1 +1 @@
u52 u53

View File

@ -598,7 +598,7 @@
~ GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight); ~ GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight);
~ GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 1.0f); ~ GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
> DELETE 2 @ 2 : 4 > DELETE 1 @ 1 : 4
> DELETE 5 @ 5 : 6 > DELETE 5 @ 5 : 6

View File

@ -5,13 +5,12 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> INSERT 2 : 7 @ 2 > INSERT 2 : 6 @ 2
+ import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; + import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
+ import net.lax1dude.eaglercraft.v1_8.opengl.VertexFormat; + import net.lax1dude.eaglercraft.v1_8.opengl.VertexFormat;
+ import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer; + import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
+ import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DeferredStateManager; + import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DeferredStateManager;
+ import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.DynamicLightsStateManager;
> DELETE 4 @ 4 : 5 > DELETE 4 @ 4 : 5

View File

@ -89,7 +89,17 @@
~ stackTrace.append("\tat ").append(s).append('\n'); ~ stackTrace.append("\tat ").append(s).append('\n');
~ }); ~ });
> CHANGE 1 : 2 @ 1 : 12 > CHANGE 1 : 8 @ 1 : 9
~ Throwable t = this.cause.getCause();
~ while (t != null) {
~ stackTrace.append("Caused by: " + t.toString()).append('\n');
~ EagRuntime.getStackTrace(t, (s) -> {
~ stackTrace.append("\tat ").append(s).append('\n');
~ });
~ t = t.getCause();
> CHANGE 2 : 3 @ 2 : 3
~ return stackTrace.toString(); ~ return stackTrace.toString();

View File

@ -16,7 +16,7 @@
~ eaglercraft.resourcePack.load.loading=Loading resource pack... ~ eaglercraft.resourcePack.load.loading=Loading resource pack...
~ eaglercraft.resourcePack.load.deleting=Deleting resource pack... ~ eaglercraft.resourcePack.load.deleting=Deleting resource pack...
> INSERT 1 : 247 @ 1 > INSERT 1 : 243 @ 1
+ eaglercraft.gui.exitKey=Use '%s' to close this screen! + eaglercraft.gui.exitKey=Use '%s' to close this screen!
+ eaglercraft.gui.exitKeyRetarded=Use Backtick (`) to close this screen! + eaglercraft.gui.exitKeyRetarded=Use Backtick (`) to close this screen!
@ -213,10 +213,6 @@
+ eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.6=ON: enable raytracing (slower) + eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.6=ON: enable raytracing (slower)
+ eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.7=OFF: disable raytracing (faster) + eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.7=OFF: disable raytracing (faster)
+ +
+ eaglercraft.shaders.gui.option.LIGHT_SHAFTS.desc.0=Render god rays (light shafts) for sunlight and moonlight shadows
+ eaglercraft.shaders.gui.option.LIGHT_SHAFTS.desc.2=ON: render god rays (slower)
+ eaglercraft.shaders.gui.option.LIGHT_SHAFTS.desc.3=OFF: disable god rays (faster)
+
+ eaglercraft.shaders.gui.option.POST_LENS_DISTORION.label=Lens Distort + eaglercraft.shaders.gui.option.POST_LENS_DISTORION.label=Lens Distort
+ +
+ eaglercraft.shaders.gui.option.POST_LENS_DISTORION.desc.0=Renders chromatic abberation and lens distorion + eaglercraft.shaders.gui.option.POST_LENS_DISTORION.desc.0=Renders chromatic abberation and lens distorion

View File

@ -573,6 +573,10 @@ public class PlatformOpenGL {
glDrawElements(mode, count, type, offset); glDrawElements(mode, count, type, offset);
} }
public static void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset) {
glDrawRangeElements(mode, start, end, count, type, offset);
}
public static void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced) { public static void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced) {
switch(instancingImpl) { switch(instancingImpl) {
case INSTANCE_IMPL_CORE: case INSTANCE_IMPL_CORE:

View File

@ -10,7 +10,7 @@ public class EaglercraftVersion {
/// Customize these to fit your fork: /// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX"; public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u52"; public static final String projectForkVersion = "u53";
public static final String projectForkVendor = "lax1dude"; public static final String projectForkVendor = "lax1dude";
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
@ -20,20 +20,20 @@ public class EaglercraftVersion {
public static final String projectOriginName = "EaglercraftX"; public static final String projectOriginName = "EaglercraftX";
public static final String projectOriginAuthor = "lax1dude"; public static final String projectOriginAuthor = "lax1dude";
public static final String projectOriginRevision = "1.8"; public static final String projectOriginRevision = "1.8";
public static final String projectOriginVersion = "u52"; public static final String projectOriginVersion = "u53";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
// EPK Version Identifier // EPK Version Identifier
public static final String EPKVersionIdentifier = "u52"; // Set to null to disable EPK version check public static final String EPKVersionIdentifier = "u53"; // Set to null to disable EPK version check
// Updating configuration // Updating configuration
public static final boolean enableUpdateService = true; public static final boolean enableUpdateService = true;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client"; public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 52; public static final int updateBundlePackageVersionInt = 53;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName; public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;

View File

@ -19,7 +19,6 @@ package net.lax1dude.eaglercraft.v1_8.mojang.authlib;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder; import com.google.common.collect.MultimapBuilder;

View File

@ -94,7 +94,7 @@ public class TexturesProperty {
if(meta != null) { if(meta != null) {
String modelStr = meta.optString("model"); String modelStr = meta.optString("model");
if(modelStr != null && modelStr.equalsIgnoreCase("slim")) { if(modelStr != null && modelStr.equalsIgnoreCase("slim")) {
model = SkinModel.STEVE; model = SkinModel.ALEX;
} }
} }
} }

View File

@ -26,7 +26,6 @@ class DisplayList {
int attribs = -1; int attribs = -1;
int mode = -1; int mode = -1;
int count = 0; int count = 0;
boolean bindQuad16 = false; byte bindQuad = 0;
boolean bindQuad32 = false;
} }

View File

@ -40,7 +40,7 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
public class EaglercraftGPU { public class EaglercraftGPU {
static final GLObjectRecycler<IBufferGL> arrayBufferRecycler = new GLObjectRecycler<IBufferGL>(32) { static final GLObjectRecycler<IBufferGL> arrayBufferRecycler = new GLObjectRecycler<IBufferGL>(256) {
@Override @Override
protected IBufferGL create() { protected IBufferGL create() {
@ -49,7 +49,14 @@ public class EaglercraftGPU {
@Override @Override
protected void invalidate(IBufferGL object) { protected void invalidate(IBufferGL object) {
// Don't bother IBufferGL old = currentArrayBuffer;
if (old != object) {
_wglBindBuffer(GL_ARRAY_BUFFER, object);
}
_wglBufferData(GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
if (old != object) {
_wglBindBuffer(GL_ARRAY_BUFFER, old);
}
} }
@Override @Override
@ -59,7 +66,7 @@ public class EaglercraftGPU {
}; };
static final GLObjectRecycler<IBufferGL> elementArrayBufferRecycler = new GLObjectRecycler<IBufferGL>(32) { static final GLObjectRecycler<IBufferGL> elementArrayBufferRecycler = new GLObjectRecycler<IBufferGL>(256) {
@Override @Override
protected IBufferGL create() { protected IBufferGL create() {
@ -68,7 +75,22 @@ public class EaglercraftGPU {
@Override @Override
protected void invalidate(IBufferGL object) { protected void invalidate(IBufferGL object) {
// Don't bother IVertexArrayGL oldArray = currentVertexArray;
boolean vao = !emulatedVAOs;
if (vao && vertexArrayCapable && oldArray != null) {
_wglBindVertexArray(null);
}
IBufferGL old = currentEmulatedVAOIndexBuffer;
if (vao || old != object) {
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object);
}
_wglBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
if (!vao && old != object) {
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, old);
}
if (vao && vertexArrayCapable && oldArray != null) {
_wglBindVertexArray(oldArray);
}
} }
@Override @Override
@ -211,8 +233,7 @@ public class EaglercraftGPU {
if(dp.vertexArray == null) { if(dp.vertexArray == null) {
dp.vertexArray = createGLVertexArray(); dp.vertexArray = createGLVertexArray();
dp.bindQuad16 = false; dp.bindQuad = 0;
dp.bindQuad32 = false;
} }
if(dp.vertexBuffer == null) { if(dp.vertexBuffer == null) {
dp.vertexBuffer = createGLArrayBuffer(); dp.vertexBuffer = createGLArrayBuffer();
@ -252,8 +273,7 @@ public class EaglercraftGPU {
if(dp.vertexArray == null) { if(dp.vertexArray == null) {
dp.vertexArray = createGLVertexArray(); dp.vertexArray = createGLVertexArray();
dp.bindQuad16 = false; dp.bindQuad = 0;
dp.bindQuad32 = false;
} }
if(dp.vertexBuffer == null) { if(dp.vertexBuffer == null) {
dp.vertexBuffer = createGLArrayBuffer(); dp.vertexBuffer = createGLArrayBuffer();
@ -280,21 +300,19 @@ public class EaglercraftGPU {
if(dp.mode == GL_QUADS) { if(dp.mode == GL_QUADS) {
int cnt = dp.count; int cnt = dp.count;
if(cnt > quad16MaxVertices) { if(cnt > quad16MaxVertices) {
if(!dp.bindQuad32) { if(dp.bindQuad != 32) {
dp.bindQuad16 = false; dp.bindQuad = 32;
dp.bindQuad32 = true;
attachQuad32EmulationBuffer(cnt, true); attachQuad32EmulationBuffer(cnt, true);
}else { }else {
attachQuad32EmulationBuffer(cnt, false); attachQuad32EmulationBuffer(cnt, false);
} }
p.drawElements(GL_TRIANGLES, (cnt >> 2) * 6, GL_UNSIGNED_INT, 0); p.drawRangeElements(GL_TRIANGLES, 0, cnt - 1, (cnt >> 2) * 6, GL_UNSIGNED_INT, 0);
}else { }else {
if(!dp.bindQuad16) { if(dp.bindQuad != 16) {
dp.bindQuad16 = true; dp.bindQuad = 16;
dp.bindQuad32 = false;
attachQuad16EmulationBuffer(true); attachQuad16EmulationBuffer(true);
} }
p.drawElements(GL_TRIANGLES, (cnt >> 2) * 6, GL_UNSIGNED_SHORT, 0); p.drawRangeElements(GL_TRIANGLES, 0, cnt - 1, (cnt >> 2) * 6, GL_UNSIGNED_SHORT, 0);
} }
}else { }else {
p.drawArrays(dp.mode, 0, dp.count); p.drawArrays(dp.mode, 0, dp.count);
@ -560,6 +578,21 @@ public class EaglercraftGPU {
_wglDrawElements(mode, count, type, offset); _wglDrawElements(mode, count, type, offset);
} }
public static void drawRangeElements(int mode, int start, int end, int count, int type, int offset) {
if(emulatedVAOs) {
if(currentVertexArray == null) {
logger.warn("Skipping draw call with emulated VAO because no known VAO is bound!");
return;
}
((SoftGLVertexArray)currentVertexArray).transitionToState(emulatedVAOState, true);
}
if(glesVers >= 300) {
_wglDrawRangeElements(mode, start, end, count, type, offset);
}else {
_wglDrawElements(mode, count, type, offset);
}
}
public static void drawArraysInstanced(int mode, int first, int count, int instances) { public static void drawArraysInstanced(int mode, int first, int count, int instances) {
if(emulatedVAOs) { if(emulatedVAOs) {
if(currentVertexArray == null) { if(currentVertexArray == null) {
@ -768,7 +801,7 @@ public class EaglercraftGPU {
displayListBuffer.put(buffer); displayListBuffer.put(buffer);
lastRender = null; lastRender = null;
}else { }else {
lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib).update(); lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib, mode == GL_QUADS).update();
lastRender.drawDirectArrays(mode, 0, count); lastRender.drawDirectArrays(mode, 0, count);
lastMode = mode; lastMode = mode;
lastCount = count; lastCount = count;
@ -845,7 +878,7 @@ public class EaglercraftGPU {
v3 = v2 + 1; v3 = v2 + 1;
v4 = v3 + 1; v4 = v3 + 1;
buf.put(v1 | (v2 << 16)); buf.put(v1 | (v2 << 16));
buf.put(v4 | (v2 << 16)); buf.put(v3 | (v1 << 16));
buf.put(v3 | (v4 << 16)); buf.put(v3 | (v4 << 16));
} }
buf.flip(); buf.flip();
@ -862,7 +895,7 @@ public class EaglercraftGPU {
v3 = v2 + 1; v3 = v2 + 1;
v4 = v3 + 1; v4 = v3 + 1;
buf.put(v1); buf.put(v2); buf.put(v1); buf.put(v2);
buf.put(v4); buf.put(v2); buf.put(v3); buf.put(v1);
buf.put(v3); buf.put(v4); buf.put(v3); buf.put(v4);
} }
buf.flip(); buf.flip();
@ -891,7 +924,7 @@ public class EaglercraftGPU {
} }
FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update(); FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update();
EaglercraftGPU.bindGLVertexArray(mesh.vertexArray); EaglercraftGPU.bindGLVertexArray(mesh.vertexArray);
p.drawElements(GL_TRIANGLES, mesh.indexCount, GL_UNSIGNED_SHORT, 0); p.drawRangeElements(GL_TRIANGLES, 0, mesh.vertexCount - 1, mesh.indexCount, GL_UNSIGNED_SHORT, 0);
} }
static int glesVers = -1; static int glesVers = -1;

View File

@ -30,12 +30,9 @@ import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL; import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL; import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL; import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.StreamBuffer.StreamBufferInstance;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.DynamicLightsStateManager;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f; import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
import net.lax1dude.eaglercraft.v1_8.vector.Vector4f; import net.lax1dude.eaglercraft.v1_8.vector.Vector4f;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
@ -61,7 +58,7 @@ public class FixedFunctionPipeline {
(GlStateManager.stateEnableShaderBlendColor ? STATE_ENABLE_BLEND_ADD : 0); (GlStateManager.stateEnableShaderBlendColor ? STATE_ENABLE_BLEND_ADD : 0);
} }
static FixedFunctionPipeline setupDirect(ByteBuffer buffer, int attrib) { static FixedFunctionPipeline setupDirect(ByteBuffer buffer, int attrib, boolean quads) {
FixedFunctionPipeline self; FixedFunctionPipeline self;
int baseState = attrib | getFragmentState(); int baseState = attrib | getFragmentState();
if(GlStateManager.stateUseExtensionPipeline) { if(GlStateManager.stateUseExtensionPipeline) {
@ -74,13 +71,13 @@ public class FixedFunctionPipeline {
self = getPipelineInstanceCore(baseState); self = getPipelineInstanceCore(baseState);
} }
StreamBufferInstance sb = self.streamBuffer.getBuffer(buffer.remaining()); EaglercraftGPU.bindGLVertexArray(self.getDirectModeVertexArray());
self.currentVertexArray = sb;
EaglercraftGPU.bindGLVertexArray(sb.getVertexArray()); int off = StreamBuffer.uploadData(self.attribStride, buffer.remaining() / self.attribStride, quads);
EaglercraftGPU.bindGLArrayBuffer(sb.getVertexBuffer());
_wglBufferSubData(GL_ARRAY_BUFFER, 0, buffer); _wglBufferSubData(GL_ARRAY_BUFFER, off * self.attribStride, buffer);
self.directBaseOffset = off;
return self; return self;
} }
@ -132,16 +129,19 @@ public class FixedFunctionPipeline {
} }
static FixedFunctionPipeline setupRenderDisplayList(int attribs) { static FixedFunctionPipeline setupRenderDisplayList(int attribs) {
FixedFunctionPipeline self;
int baseState = attribs | getFragmentState(); int baseState = attribs | getFragmentState();
if(GlStateManager.stateUseExtensionPipeline) { if(GlStateManager.stateUseExtensionPipeline) {
if(extensionProvider != null) { if(extensionProvider != null) {
return getPipelineInstanceExt(baseState, extensionProvider.getCurrentExtensionStateBits(baseState)); self = getPipelineInstanceExt(baseState, extensionProvider.getCurrentExtensionStateBits(baseState));
}else { }else {
throw new IllegalStateException("No extension pipeline is available!"); throw new IllegalStateException("No extension pipeline is available!");
} }
}else { }else {
return getPipelineInstanceCore(baseState); self = getPipelineInstanceCore(baseState);
} }
return self;
} }
void drawArrays(int mode, int offset, int count) { void drawArrays(int mode, int offset, int count) {
@ -151,24 +151,26 @@ public class FixedFunctionPipeline {
void drawDirectArrays(int mode, int offset, int count) { void drawDirectArrays(int mode, int offset, int count) {
EaglercraftGPU.bindGLShaderProgram(shaderProgram); EaglercraftGPU.bindGLShaderProgram(shaderProgram);
offset += directBaseOffset;
if(mode == GL_QUADS) { if(mode == GL_QUADS) {
StreamBufferInstance sb = currentVertexArray; int offset2 = (offset >> 2) * 6;
if(count > EaglercraftGPU.quad16MaxVertices) { int count2 = (count >> 2) * 6;
if(!sb.bindQuad32) { if(offset + count > EaglercraftGPU.quad16MaxVertices) {
sb.bindQuad16 = false; if(directQuads != 32) {
sb.bindQuad32 = true; directQuads = 32;
EaglercraftGPU.attachQuad32EmulationBuffer(count, true); EaglercraftGPU.attachQuad32EmulationBuffer(count, true);
}else { }else {
EaglercraftGPU.attachQuad32EmulationBuffer(count, false); EaglercraftGPU.attachQuad32EmulationBuffer(count, false);
} }
EaglercraftGPU.drawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_INT, 0); EaglercraftGPU.drawRangeElements(GL_TRIANGLES, offset, offset + count - 1, count2, GL_UNSIGNED_INT,
offset2 << 2);
}else { }else {
if(!sb.bindQuad16) { if(directQuads != 16) {
sb.bindQuad16 = true; directQuads = 16;
sb.bindQuad32 = false;
EaglercraftGPU.attachQuad16EmulationBuffer(true); EaglercraftGPU.attachQuad16EmulationBuffer(true);
} }
EaglercraftGPU.drawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_SHORT, 0); EaglercraftGPU.drawRangeElements(GL_TRIANGLES, offset, offset + count - 1, count2, GL_UNSIGNED_SHORT,
offset2 << 1);
} }
}else { }else {
EaglercraftGPU.drawArrays(mode, offset, count); EaglercraftGPU.drawArrays(mode, offset, count);
@ -180,6 +182,11 @@ public class FixedFunctionPipeline {
EaglercraftGPU.drawElements(mode, count, type, offset); EaglercraftGPU.drawElements(mode, count, type, offset);
} }
void drawRangeElements(int mode, int start, int end, int count, int type, int offset) {
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
EaglercraftGPU.drawRangeElements(mode, start, end, count, type, offset);
}
private static IExtPipelineCompiler extensionProvider; private static IExtPipelineCompiler extensionProvider;
public static void loadExtensionPipeline(IExtPipelineCompiler provider) { public static void loadExtensionPipeline(IExtPipelineCompiler provider) {
@ -423,9 +430,9 @@ public class FixedFunctionPipeline {
private float stateAlphaTestRef = -999.0f; private float stateAlphaTestRef = -999.0f;
private final IUniformGL stateLightsEnabledUniform1i; private final IUniformGL stateLightsEnabledUniform1i;
private final IUniformGL[] stateLightsVectorsArrayUniform4f = new IUniformGL[4]; private final IUniformGL[] stateLightsVectorsArrayUniform4f = new IUniformGL[2];
private int stateLightsEnabled = -1; private int stateLightsEnabled = -1;
private final Vector4f[] stateLightsVectors = new Vector4f[4]; private final Vector4f[] stateLightsVectors = new Vector4f[2];
private int stateLightingSerial = -1; private int stateLightingSerial = -1;
private final IUniformGL stateLightingAmbientUniform3f; private final IUniformGL stateLightingAmbientUniform3f;
@ -496,8 +503,9 @@ public class FixedFunctionPipeline {
private float stateAnisotropicFixH = -999.0f; private float stateAnisotropicFixH = -999.0f;
private float stateAnisotropicFixSerial = 0; private float stateAnisotropicFixSerial = 0;
private final StreamBuffer streamBuffer; private IVertexArrayGL directVertexArray;
private StreamBufferInstance currentVertexArray = null; private int directBaseOffset;
private byte directQuads;
private static FloatBuffer matrixCopyBuffer = null; private static FloatBuffer matrixCopyBuffer = null;
@ -572,39 +580,6 @@ public class FixedFunctionPipeline {
} }
throw new IllegalStateException("Program could not be linked!"); throw new IllegalStateException("Program could not be linked!");
} }
streamBuffer = new StreamBuffer((vertexArray, vertexBuffer) -> {
EaglercraftGPU.bindGLVertexArray(vertexArray);
EaglercraftGPU.bindVAOGLArrayBuffer(vertexBuffer);
EaglercraftGPU.enableVertexAttribArray(0);
EaglercraftGPU.vertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE,
VertexFormat.COMPONENT_POSITION_FORMAT, false, attribStride, 0);
if(attribTextureIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribTextureIndex);
EaglercraftGPU.vertexAttribPointer(attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE,
VertexFormat.COMPONENT_TEX_FORMAT, false, attribStride, attribTextureOffset);
}
if(attribColorIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribColorIndex);
EaglercraftGPU.vertexAttribPointer(attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE,
VertexFormat.COMPONENT_COLOR_FORMAT, true, attribStride, attribColorOffset);
}
if(attribNormalIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribNormalIndex);
EaglercraftGPU.vertexAttribPointer(attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE,
VertexFormat.COMPONENT_NORMAL_FORMAT, true, attribStride, attribNormalOffset);
}
if(attribLightmapIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribLightmapIndex);
EaglercraftGPU.vertexAttribPointer(attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE,
VertexFormat.COMPONENT_LIGHTMAP_FORMAT, false, attribStride, attribLightmapOffset);
}
});
stateEnableTexture2D = (bits & STATE_ENABLE_TEXTURE2D) != 0; stateEnableTexture2D = (bits & STATE_ENABLE_TEXTURE2D) != 0;
stateEnableLightmap = (bits & STATE_ENABLE_LIGHTMAP) != 0; stateEnableLightmap = (bits & STATE_ENABLE_LIGHTMAP) != 0;
@ -899,9 +874,7 @@ public class FixedFunctionPipeline {
_wglUniform3f(stateLightingAmbientUniform3f, r, g, b); _wglUniform3f(stateLightingAmbientUniform3f, r, g, b);
} }
} }
}
if(stateEnableMCLighting || DynamicLightsStateManager.isInDynamicLightsPass()) {
if(!stateHasAttribNormal) { if(!stateHasAttribNormal) {
serial = GlStateManager.stateNormalSerial; serial = GlStateManager.stateNormalSerial;
if(stateNormalSerial != serial) { if(stateNormalSerial != serial) {
@ -1089,13 +1062,51 @@ public class FixedFunctionPipeline {
} }
pipelineListTracker.clear(); pipelineListTracker.clear();
} }
public void destroy() {
PlatformOpenGL._wglDeleteProgram(shaderProgram);
streamBuffer.destroy();
}
public IVertexArrayGL getDirectModeVertexArray() { public IVertexArrayGL getDirectModeVertexArray() {
return currentVertexArray.vertexArray; if (directVertexArray == null) {
directVertexArray = EaglercraftGPU.createGLVertexArray();
EaglercraftGPU.bindGLVertexArray(directVertexArray);
EaglercraftGPU.bindVAOGLArrayBuffer(StreamBuffer.getBuffer());
EaglercraftGPU.enableVertexAttribArray(0);
EaglercraftGPU.vertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE,
VertexFormat.COMPONENT_POSITION_FORMAT, false, attribStride, 0);
if (attribTextureIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribTextureIndex);
EaglercraftGPU.vertexAttribPointer(attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE,
VertexFormat.COMPONENT_TEX_FORMAT, false, attribStride, attribTextureOffset);
}
if (attribColorIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribColorIndex);
EaglercraftGPU.vertexAttribPointer(attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE,
VertexFormat.COMPONENT_COLOR_FORMAT, true, attribStride, attribColorOffset);
}
if (attribNormalIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribNormalIndex);
EaglercraftGPU.vertexAttribPointer(attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE,
VertexFormat.COMPONENT_NORMAL_FORMAT, true, attribStride, attribNormalOffset);
}
if (attribLightmapIndex != -1) {
EaglercraftGPU.enableVertexAttribArray(attribLightmapIndex);
EaglercraftGPU.vertexAttribPointer(attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE,
VertexFormat.COMPONENT_LIGHTMAP_FORMAT, false, attribStride, attribLightmapOffset);
}
return directVertexArray;
}
return directVertexArray;
} }
public void destroy() {
_wglDeleteProgram(shaderProgram);
if (directVertexArray != null) {
EaglercraftGPU.destroyGLVertexArray(directVertexArray);
}
}
} }

View File

@ -44,7 +44,7 @@ public class FixedFunctionShader {
public static final String FILENAME_VSH = "/assets/eagler/glsl/core.vsh"; public static final String FILENAME_VSH = "/assets/eagler/glsl/core.vsh";
public static final String FILENAME_FSH = "/assets/eagler/glsl/core.fsh"; public static final String FILENAME_FSH = "/assets/eagler/glsl/core.fsh";
public static final String PRECISION_INT = "lowp"; public static final String PRECISION_INT = "mediump";
public static final String PRECISION_FLOAT = "highp"; public static final String PRECISION_FLOAT = "highp";
public static final String PRECISION_SAMPLER = "mediump"; public static final String PRECISION_SAMPLER = "mediump";

View File

@ -76,9 +76,9 @@ public class GlStateManager {
static boolean stateMaterial = false; static boolean stateMaterial = false;
static boolean stateLighting = false; static boolean stateLighting = false;
static int stateLightsStackPointer = 0; static int stateLightsStackPointer = 0;
static final boolean[][] stateLightsEnabled = new boolean[4][8]; static final boolean[][] stateLightsEnabled = new boolean[2][8];
static final Vector4f[][] stateLightsStack = new Vector4f[4][8]; static final Vector4f[][] stateLightsStack = new Vector4f[2][8];
static final int[] stateLightingSerial = new int[4]; static final int[] stateLightingSerial = new int[2];
static float stateLightingAmbientR = 0.0f; static float stateLightingAmbientR = 0.0f;
static float stateLightingAmbientG = 0.0f; static float stateLightingAmbientG = 0.0f;

View File

@ -206,8 +206,7 @@ public class InstancedFontRenderer {
EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0); EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
EaglercraftGPU.vertexAttribDivisor(0, 0); EaglercraftGPU.vertexAttribDivisor(0, 0);
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer); EaglercraftGPU.bindVAOGLArrayBuffer(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW);
EaglercraftGPU.enableVertexAttribArray(1); EaglercraftGPU.enableVertexAttribArray(1);
EaglercraftGPU.vertexAttribPointer(1, 2, GL_SHORT, false, 10, 0); EaglercraftGPU.vertexAttribPointer(1, 2, GL_SHORT, false, 10, 0);
@ -381,7 +380,7 @@ public class InstancedFontRenderer {
int l = fontDataBuffer.limit(); int l = fontDataBuffer.limit();
fontDataBuffer.flip(); fontDataBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW); _wglBufferData(GL_ARRAY_BUFFER, (fontDataBuffer.remaining() + 0x3FF) & 0xFFFFFC00, GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, fontDataBuffer); _wglBufferSubData(GL_ARRAY_BUFFER, 0, fontDataBuffer);
fontDataBuffer.position(p); fontDataBuffer.position(p);
@ -395,7 +394,7 @@ public class InstancedFontRenderer {
int l = fontBoldDataBuffer.limit(); int l = fontBoldDataBuffer.limit();
fontBoldDataBuffer.flip(); fontBoldDataBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, fontBoldDataBuffer.capacity(), GL_STREAM_DRAW); _wglBufferData(GL_ARRAY_BUFFER, (fontBoldDataBuffer.remaining() + 0x3FF) & 0xFFFFFC00, GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, fontBoldDataBuffer); _wglBufferSubData(GL_ARRAY_BUFFER, 0, fontBoldDataBuffer);
fontBoldDataBuffer.position(p); fontBoldDataBuffer.position(p);

View File

@ -187,8 +187,7 @@ public class InstancedParticleRenderer {
EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0); EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
EaglercraftGPU.vertexAttribDivisor(0, 0); EaglercraftGPU.vertexAttribDivisor(0, 0);
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer); EaglercraftGPU.bindVAOGLArrayBuffer(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
EaglercraftGPU.enableVertexAttribArray(1); EaglercraftGPU.enableVertexAttribArray(1);
EaglercraftGPU.vertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0); EaglercraftGPU.vertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
@ -315,7 +314,7 @@ public class InstancedParticleRenderer {
int l = particleBuffer.limit(); int l = particleBuffer.limit();
particleBuffer.flip(); particleBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW); _wglBufferData(GL_ARRAY_BUFFER, (particleBuffer.remaining() + 0xFFF) & 0xFFFFF000, GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer); _wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
particleBuffer.position(p); particleBuffer.position(p);

View File

@ -16,108 +16,53 @@
package net.lax1dude.eaglercraft.v1_8.opengl; package net.lax1dude.eaglercraft.v1_8.opengl;
import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL; import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*; import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/**
* This streaming implementation was designed by reverse engineering the OpenGL
* driver that powers most Intel-based Chromebooks, performance may vary on
* other platforms
*/
public class StreamBuffer { public class StreamBuffer {
public static final int poolSize = 4; protected static IBufferGL buffer = null;
protected static final PoolInstance[] pool = new PoolInstance[poolSize]; protected static int currentOffset = 0;
protected static int poolBufferID = 0; protected static int currentSize = 0;
static { public static IBufferGL getBuffer() {
for(int i = 0; i < poolSize; ++i) {
pool[i] = new PoolInstance();
}
}
protected static class PoolInstance {
protected IBufferGL vertexBuffer = null;
protected int vertexBufferSize = 0;
}
private static void resizeInstance(PoolInstance instance, int requiredMemory) {
IBufferGL buffer = instance.vertexBuffer;
if (buffer == null) { if (buffer == null) {
buffer = _wglGenBuffers(); return buffer = _wglGenBuffers();
instance.vertexBuffer = buffer;
} }
int newSize = instance.vertexBufferSize; return buffer;
if (newSize < requiredMemory) {
newSize = (requiredMemory + 0xFFFF) & 0xFFFF0000;
instance.vertexBufferSize = newSize;
}
EaglercraftGPU.bindGLArrayBuffer(buffer);
_wglBufferData(GL_ARRAY_BUFFER, newSize, GL_STREAM_DRAW);
} }
protected StreamBufferInstance[] buffers; public static int uploadData(int elSize, int elCount, boolean quads) {
EaglercraftGPU.bindGLArrayBuffer(getBuffer());
protected final IStreamBufferInitializer initializer; int off = (currentOffset + elSize - 1) / elSize;
if (quads) {
public static class StreamBufferInstance { off = (off + 3) & -4;
protected PoolInstance poolInstance = null;
protected IVertexArrayGL vertexArray = null;
public boolean bindQuad16 = false;
public boolean bindQuad32 = false;
public IVertexArrayGL getVertexArray() {
return vertexArray;
} }
int offBytes = off * elSize;
public IBufferGL getVertexBuffer() { int reqBytes = elCount * elSize;
return poolInstance.vertexBuffer; if (currentSize - offBytes >= reqBytes) {
} currentOffset = offBytes + reqBytes;
return off;
} } else {
currentOffset = 0;
public static interface IStreamBufferInitializer { currentSize = (reqBytes + 0xFFFF) & 0xFFFFF000;
void initialize(IVertexArrayGL vertexArray, IBufferGL vertexBuffer); _wglBufferData(GL_ARRAY_BUFFER, currentSize, GL_STREAM_DRAW);
} return 0;
public StreamBuffer(IStreamBufferInitializer initializer) {
this.buffers = new StreamBufferInstance[poolSize];
for(int i = 0; i < this.buffers.length; ++i) {
StreamBufferInstance j = new StreamBufferInstance();
j.poolInstance = pool[i];
this.buffers[i] = j;
}
this.initializer = initializer;
}
public StreamBufferInstance getBuffer(int requiredMemory) {
StreamBufferInstance next = buffers[poolBufferID++ % buffers.length];
resizeInstance(next.poolInstance, requiredMemory);
if(next.vertexArray == null) {
next.vertexArray = EaglercraftGPU.createGLVertexArray();
initializer.initialize(next.vertexArray, next.poolInstance.vertexBuffer);
}
return next;
}
public void destroy() {
for(int i = 0; i < buffers.length; ++i) {
StreamBufferInstance next = buffers[i];
if(next.vertexArray != null) {
EaglercraftGPU.destroyGLVertexArray(next.vertexArray);
}
} }
} }
public static void destroyPool() { public static void destroyPool() {
for(int i = 0; i < pool.length; ++i) { if (buffer != null) {
if(pool[i].vertexBuffer != null) { _wglDeleteBuffers(buffer);
_wglDeleteBuffers(pool[i].vertexBuffer); buffer = null;
pool[i].vertexBuffer = null;
}
} }
} }

View File

@ -316,7 +316,8 @@ public class LensFlareMeshRenderer {
_wglUniform3f(streaksProgram.uniforms.u_flareColor3f, v.x * mag * 0.5f, v.y * mag * 0.5f, v.z * mag * 0.5f); _wglUniform3f(streaksProgram.uniforms.u_flareColor3f, v.x * mag * 0.5f, v.y * mag * 0.5f, v.z * mag * 0.5f);
EaglercraftGPU.bindGLVertexArray(streaksVertexArray); EaglercraftGPU.bindGLVertexArray(streaksVertexArray);
_wglDrawElements(GL_TRIANGLES, streaksVertexCount + (streaksVertexCount >> 1), GL_UNSIGNED_SHORT, 0); _wglDrawRangeElements(GL_TRIANGLES, 0, streaksVertexCount - 1, streaksVertexCount + (streaksVertexCount >> 1),
GL_UNSIGNED_SHORT, 0);
ghostsProgram.useProgram(); ghostsProgram.useProgram();

View File

@ -46,8 +46,8 @@ public class DynamicLightBucketLoader {
private int currentLightSourceBucketId = -1; private int currentLightSourceBucketId = -1;
private int lightingBufferSliceLength = -1; private int lightingBufferSliceLength = -1;
public static final int MAX_LIGHTS_PER_CHUNK = 12; public static final int MAX_LIGHTS_PER_CHUNK = 8;
public static final int LIGHTING_BUFFER_LENGTH = 16 * MAX_LIGHTS_PER_CHUNK + 16; public static final int LIGHTING_BUFFER_LENGTH = 8 * MAX_LIGHTS_PER_CHUNK + 16;
private final int lightSourceBucketsWidth; private final int lightSourceBucketsWidth;
private final int lightSourceBucketsHeight; private final int lightSourceBucketsHeight;
@ -114,26 +114,36 @@ public class DynamicLightBucketLoader {
int ser = currentLightSourceBucket.getEaglerSerial(); int ser = currentLightSourceBucket.getEaglerSerial();
int max = currentLightSourceBucket.size(); int max = currentLightSourceBucket.size();
if(max > 0) { if(max > 0) {
if(max > MAX_LIGHTS_PER_CHUNK) {
max = MAX_LIGHTS_PER_CHUNK;
}
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData); EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
int offset = currentLightSourceBucketId * lightingBufferSliceLength; int offset = currentLightSourceBucketId * lightingBufferSliceLength;
if (lightSourceBucketsSerials[currentLightSourceBucketId] != ser if (lightSourceBucketsSerials[currentLightSourceBucketId] != ser
|| lightSourceRenderPosSerials[currentLightSourceBucketId] != currentRenderPosSerial) { || lightSourceRenderPosSerials[currentLightSourceBucketId] != currentRenderPosSerial) {
lightSourceBucketsSerials[currentLightSourceBucketId] = ser; lightSourceBucketsSerials[currentLightSourceBucketId] = ser;
lightSourceRenderPosSerials[currentLightSourceBucketId] = currentRenderPosSerial; lightSourceRenderPosSerials[currentLightSourceBucketId] = currentRenderPosSerial;
if(max > MAX_LIGHTS_PER_CHUNK) { int bucketXOff = -relativeBlockX & -16;
max = MAX_LIGHTS_PER_CHUNK; int bucketYOff = -relativeBlockY & -16;
} int bucketZOff = -relativeBlockZ & -16;
chunkLightingDataCopyBuffer.clear(); chunkLightingDataCopyBuffer.clear();
chunkLightingDataCopyBuffer.putInt(
((bucketXOff & 0xFF) << 8) |
((bucketYOff & 0xFF) << 16) |
((bucketZOff & 0xFF) << 24)
);
chunkLightingDataCopyBuffer.putInt(max); chunkLightingDataCopyBuffer.putInt(max);
chunkLightingDataCopyBuffer.putInt(0); //padding chunkLightingDataCopyBuffer.putInt(0); // padding
chunkLightingDataCopyBuffer.putInt(0); //padding chunkLightingDataCopyBuffer.putInt(0); // padding
chunkLightingDataCopyBuffer.putInt(0); //padding
for(int i = 0; i < max; ++i) { for(int i = 0; i < max; ++i) {
DynamicLightInstance dl = currentLightSourceBucket.get(i); DynamicLightInstance dl = currentLightSourceBucket.get(i);
chunkLightingDataCopyBuffer.putFloat((float)(dl.posX - currentRenderX)); int x = (int)((dl.posX - currentRenderX + bucketXOff) * (1.0f / 0.0009765923f));
chunkLightingDataCopyBuffer.putFloat((float)(dl.posY - currentRenderY)); int y = (int)((dl.posY - currentRenderY + bucketYOff) * (1.0f / 0.0009765923f));
chunkLightingDataCopyBuffer.putFloat((float)(dl.posZ - currentRenderZ)); int z = (int)((dl.posZ - currentRenderZ + bucketZOff) * (1.0f / 0.0009765923f));
chunkLightingDataCopyBuffer.putFloat(dl.radius); int r = (int)(dl.radius * (1.0f / 0.0009765923f));
if (r > 32767) r = 32767;
chunkLightingDataCopyBuffer.putInt((x & 0xFFFF) | (z << 16));
chunkLightingDataCopyBuffer.putInt((y & 0xFFFF) | (r << 16));
} }
chunkLightingDataCopyBuffer.flip(); chunkLightingDataCopyBuffer.flip();
_wglBufferSubData(_GL_UNIFORM_BUFFER, offset, chunkLightingDataCopyBuffer); _wglBufferSubData(_GL_UNIFORM_BUFFER, offset, chunkLightingDataCopyBuffer);

View File

@ -204,6 +204,8 @@ public class PlatformOpenGL {
public static native void _wglDrawElements(int mode, int count, int type, int offset); public static native void _wglDrawElements(int mode, int count, int type, int offset);
public static native void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset);
public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced); public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced);
public static native void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced); public static native void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced);

View File

@ -1 +1 @@
u52 u53

View File

@ -63,7 +63,7 @@ uniform float u_alphaTestRef1f;
#ifdef COMPILE_ENABLE_MC_LIGHTING #ifdef COMPILE_ENABLE_MC_LIGHTING
uniform int u_lightsEnabled1i; uniform int u_lightsEnabled1i;
uniform vec4 u_lightsDirections4fv[4]; uniform vec4 u_lightsDirections4fv[2];
uniform vec3 u_lightsAmbient3f; uniform vec3 u_lightsAmbient3f;
#ifndef COMPILE_NORMAL_ATTRIB #ifndef COMPILE_NORMAL_ATTRIB
uniform vec3 u_uniformNormal3f; uniform vec3 u_uniformNormal3f;
@ -166,20 +166,14 @@ void main() {
#else #else
vec3 normal = u_uniformNormal3f; vec3 normal = u_uniformNormal3f;
#endif #endif
float diffuse = 0.0;
vec4 light; vec4 light;
#ifdef EAGLER_HAS_GLES_300 float diffuse = 0.0;
for(int i = 0; i < u_lightsEnabled1i; ++i) { for(int i = 0; i < 2; ++i) {
#else if(i >= u_lightsEnabled1i) {
for(int i = 0; i < 4; ++i) {
#endif
light = u_lightsDirections4fv[i];
diffuse += max(dot(light.xyz, normal), 0.0) * light.w;
#ifndef EAGLER_HAS_GLES_300
if(i + 1 >= u_lightsEnabled1i) {
break; break;
} }
#endif light = u_lightsDirections4fv[i];
diffuse += max(dot(light.xyz, normal), 0.0) * light.w;
} }
color.rgb *= min(u_lightsAmbient3f + vec3(diffuse), 1.0); color.rgb *= min(u_lightsAmbient3f + vec3(diffuse), 1.0);
#endif #endif

View File

@ -20,7 +20,6 @@ precision lowp int;
precision mediump float; precision mediump float;
precision mediump sampler2D; precision mediump sampler2D;
in vec4 v_position4f;
in vec2 v_texCoord2f; in vec2 v_texCoord2f;
in vec4 v_color4f; in vec4 v_color4f;
in vec2 v_lightmap2f; in vec2 v_lightmap2f;
@ -30,16 +29,6 @@ layout(location = 0) out vec4 output4f;
uniform sampler2D u_inputTexture; uniform sampler2D u_inputTexture;
uniform sampler2D u_lightmapTexture; uniform sampler2D u_lightmapTexture;
uniform mat4 u_inverseViewMatrix4f;
layout(std140) uniform u_chunkLightingData {
mediump int u_dynamicLightCount1i;
mediump int _paddingA_;
mediump int _paddingB_;
mediump int _paddingC_;
mediump vec4 u_dynamicLightArray[12];
};
void main() { void main() {
vec4 color = texture(u_inputTexture, v_texCoord2f) * v_color4f; vec4 color = texture(u_inputTexture, v_texCoord2f) * v_color4f;
@ -47,20 +36,7 @@ void main() {
discard; discard;
} }
vec4 dlight; color *= texture(u_lightmapTexture, v_lightmap2f);
float blockLight = v_lightmap2f.x;
if(u_dynamicLightCount1i > 0) {
vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f;
worldPosition4f.xyz /= worldPosition4f.w;
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i;
for(int i = 0; i < safeLightCount; ++i) {
dlight = u_dynamicLightArray[i];
dlight.xyz = dlight.xyz - worldPosition4f.xyz;
blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight);
}
}
color *= texture(u_lightmapTexture, vec2(blockLight, v_lightmap2f.y));
output4f = color; output4f = color;
} }

View File

@ -28,21 +28,27 @@ layout(location = 3) in vec2 p_lightMap2f;
layout(location = 4) in vec2 p_particleSize_texCoordsSize_2i; layout(location = 4) in vec2 p_particleSize_texCoordsSize_2i;
layout(location = 5) in vec4 p_color4f; layout(location = 5) in vec4 p_color4f;
out vec4 v_position4f;
out vec2 v_texCoord2f; out vec2 v_texCoord2f;
out vec4 v_color4f; out vec4 v_color4f;
out vec2 v_lightmap2f; out vec2 v_lightmap2f;
uniform mat4 u_modelViewMatrix4f; uniform mat4 u_modelViewMatrix4f;
uniform mat4 u_projectionMatrix4f; uniform mat4 u_projectionMatrix4f;
uniform mat4 u_inverseViewMatrix4f;
uniform vec3 u_texCoordSize2f_particleSize1f; uniform vec3 u_texCoordSize2f_particleSize1f;
uniform vec3 u_transformParam_1_2_5_f; uniform vec3 u_transformParam_1_2_5_f;
uniform vec2 u_transformParam_3_4_f; uniform vec2 u_transformParam_3_4_f;
uniform vec4 u_color4f; uniform vec4 u_color4f;
layout(std140) uniform u_chunkLightingData {
mediump uvec2 u_dynamicLightOffsetCount2i;
mediump int _paddingA_;
mediump int _paddingB_;
mediump uvec4 u_dynamicLightArray[4];
};
void main() { void main() {
v_color4f = u_color4f * p_color4f.bgra; v_color4f = u_color4f * p_color4f.bgra;
v_lightmap2f = p_lightMap2f;
vec2 tex2f = a_position2f * 0.5 + 0.5; vec2 tex2f = a_position2f * 0.5 + 0.5;
tex2f.y = 1.0 - tex2f.y; tex2f.y = 1.0 - tex2f.y;
@ -56,6 +62,40 @@ void main() {
pos3f += u_transformParam_1_2_5_f * spos2f.xyy; pos3f += u_transformParam_1_2_5_f * spos2f.xyy;
pos3f.zx += u_transformParam_3_4_f * spos2f; pos3f.zx += u_transformParam_3_4_f * spos2f;
v_position4f = u_modelViewMatrix4f * vec4(pos3f, 1.0); vec4 pos4f = u_modelViewMatrix4f * vec4(pos3f, 1.0);
gl_Position = u_projectionMatrix4f * v_position4f; gl_Position = u_projectionMatrix4f * pos4f;
float blockLight = 0.0;
vec4 dlight;
uvec4 dlighti1, dlighti2;
if(u_dynamicLightOffsetCount2i.y > 0u) {
vec3 dlightOffset = vec3(ivec3(
int(u_dynamicLightOffsetCount2i.x << 16),
int(u_dynamicLightOffsetCount2i.x << 8),
int(u_dynamicLightOffsetCount2i.x)
) >> 24);
vec4 worldPosition4f = u_inverseViewMatrix4f * pos4f;
worldPosition4f.xyz = worldPosition4f.xyz / worldPosition4f.w + dlightOffset;
for(uint i = 0u; i < 4u; ++i) {
dlighti1 = u_dynamicLightArray[i];
dlighti2 = dlighti1 << 16;
dlight = vec4(ivec4(ivec2(dlighti2.xy), ivec2(dlighti1.xy)) >> 16) * 0.0009765923;
dlight.xyz = dlight.xyz - worldPosition4f.xyz;
blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight);
if(i * 2u + 1u >= u_dynamicLightOffsetCount2i.y) {
break;
}
dlight = vec4(ivec4(ivec2(dlighti2.zw), ivec2(dlighti1.zw)) >> 16) * 0.0009765923;
dlight.xyz = dlight.xyz - worldPosition4f.xyz;
blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight);
if(i * 2u + 2u >= u_dynamicLightOffsetCount2i.y) {
break;
}
}
}
v_lightmap2f = vec2(max(p_lightMap2f.x, blockLight), p_lightMap2f.y);
} }

View File

@ -16,7 +16,9 @@
* *
*/ */
#if defined(COMPILE_ENABLE_TEX_GEN) || defined(COMPILE_ENABLE_FOG)
in vec4 v_position4f; in vec4 v_position4f;
#endif
#ifdef COMPILE_TEXTURE_ATTRIB #ifdef COMPILE_TEXTURE_ATTRIB
in vec2 v_texture2f; in vec2 v_texture2f;
@ -61,7 +63,7 @@ uniform float u_alphaTestRef1f;
#ifdef COMPILE_ENABLE_MC_LIGHTING #ifdef COMPILE_ENABLE_MC_LIGHTING
uniform int u_lightsEnabled1i; uniform int u_lightsEnabled1i;
uniform vec4 u_lightsDirections4fv[4]; uniform vec4 u_lightsDirections4fv[2];
uniform vec3 u_lightsAmbient3f; uniform vec3 u_lightsAmbient3f;
#endif #endif
@ -88,15 +90,9 @@ uniform mat4 u_textureMat4f01;
uniform vec2 u_textureAnisotropicFix; uniform vec2 u_textureAnisotropicFix;
#endif #endif
uniform mat4 u_inverseViewMatrix4f; #ifdef COMPILE_ENABLE_LIGHTMAP
in float v_dynamicLight1f;
layout(std140) uniform u_chunkLightingData { #endif
mediump int u_dynamicLightCount1i;
mediump int _paddingA_;
mediump int _paddingB_;
mediump int _paddingC_;
mediump vec4 u_dynamicLightArray[12];
};
layout(location = 0) out vec4 output4f; layout(location = 0) out vec4 output4f;
@ -151,17 +147,9 @@ void main() {
#else #else
float blockLight = u_textureCoords02.x; float blockLight = u_textureCoords02.x;
#endif #endif
vec4 dlight;
if(u_dynamicLightCount1i > 0) { blockLight = max(blockLight, v_dynamicLight1f);
vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f;
worldPosition4f.xyz /= worldPosition4f.w;
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i;
for(int i = 0; i < safeLightCount; ++i) {
dlight = u_dynamicLightArray[i];
dlight.xyz = dlight.xyz - worldPosition4f.xyz;
blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight);
}
}
#ifdef COMPILE_LIGHTMAP_ATTRIB #ifdef COMPILE_LIGHTMAP_ATTRIB
color *= texture(u_samplerLightmap, vec2(blockLight, v_lightmap2f.y)); color *= texture(u_samplerLightmap, vec2(blockLight, v_lightmap2f.y));
#else #else
@ -179,16 +167,18 @@ void main() {
#endif #endif
#ifdef COMPILE_ENABLE_MC_LIGHTING
#ifdef COMPILE_NORMAL_ATTRIB #ifdef COMPILE_NORMAL_ATTRIB
vec3 normal = v_normal3f; vec3 normal = v_normal3f;
#else #else
vec3 normal = u_uniformNormal3f; vec3 normal = u_uniformNormal3f;
#endif #endif
#ifdef COMPILE_ENABLE_MC_LIGHTING
vec4 light; vec4 light;
float diffuse = 0.0; float diffuse = 0.0;
for(int i = 0; i < u_lightsEnabled1i; ++i) { for(int i = 0; i < 2; ++i) {
if(i >= u_lightsEnabled1i) {
break;
}
light = u_lightsDirections4fv[i]; light = u_lightsDirections4fv[i];
diffuse += max(dot(light.xyz, normal), 0.0) * light.w; diffuse += max(dot(light.xyz, normal), 0.0) * light.w;
} }

View File

@ -18,7 +18,13 @@
in vec3 a_position3f; in vec3 a_position3f;
#if defined(COMPILE_ENABLE_TEX_GEN) || defined(COMPILE_ENABLE_FOG)
#define _COMPILE_VARYING_POSITION
#endif
#ifdef _COMPILE_VARYING_POSITION
out vec4 v_position4f; out vec4 v_position4f;
#endif
#ifdef COMPILE_ENABLE_TEX_GEN #ifdef COMPILE_ENABLE_TEX_GEN
out vec3 v_objectPosition3f; out vec3 v_objectPosition3f;
@ -46,16 +52,32 @@ out vec2 v_lightmap2f;
uniform mat4 u_textureMat4f02; uniform mat4 u_textureMat4f02;
#endif #endif
#ifdef COMPILE_ENABLE_LIGHTMAP
out float v_dynamicLight1f;
#endif
uniform mat4 u_modelviewMat4f; uniform mat4 u_modelviewMat4f;
uniform mat4 u_projectionMat4f; uniform mat4 u_projectionMat4f;
uniform mat4 u_inverseViewMatrix4f;
#define TEX_MAT3(mat4In) mat3(mat4In[0].xyw,mat4In[1].xyw,mat4In[3].xyw) #define TEX_MAT3(mat4In) mat3(mat4In[0].xyw,mat4In[1].xyw,mat4In[3].xyw)
layout(std140) uniform u_chunkLightingData {
mediump uvec2 u_dynamicLightOffsetCount2i;
mediump int _paddingA_;
mediump int _paddingB_;
mediump uvec4 u_dynamicLightArray[4];
};
void main() { void main() {
#ifdef COMPILE_ENABLE_TEX_GEN #ifdef COMPILE_ENABLE_TEX_GEN
v_objectPosition3f = a_position3f; v_objectPosition3f = a_position3f;
#endif #endif
#ifndef _COMPILE_VARYING_POSITION
vec4 v_position4f;
#endif
v_position4f = u_modelviewMat4f * vec4(a_position3f, 1.0); v_position4f = u_modelviewMat4f * vec4(a_position3f, 1.0);
#ifdef COMPILE_TEXTURE_ATTRIB #ifdef COMPILE_TEXTURE_ATTRIB
@ -75,6 +97,42 @@ void main() {
vec3 v_lightmapTmp3f = TEX_MAT3(u_textureMat4f02) * vec3(a_lightmap2f, 1.0); vec3 v_lightmapTmp3f = TEX_MAT3(u_textureMat4f02) * vec3(a_lightmap2f, 1.0);
v_lightmap2f = v_lightmapTmp3f.xy / v_lightmapTmp3f.z; v_lightmap2f = v_lightmapTmp3f.xy / v_lightmapTmp3f.z;
#endif #endif
gl_Position = u_projectionMat4f * v_position4f; gl_Position = u_projectionMat4f * v_position4f;
#ifdef COMPILE_ENABLE_LIGHTMAP
float blockLight = 0.0;
vec4 dlight;
uvec4 dlighti1, dlighti2;
if(u_dynamicLightOffsetCount2i.y > 0u) {
vec3 dlightOffset = vec3(ivec3(
int(u_dynamicLightOffsetCount2i.x << 16),
int(u_dynamicLightOffsetCount2i.x << 8),
int(u_dynamicLightOffsetCount2i.x)
) >> 24);
vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f;
worldPosition4f.xyz = worldPosition4f.xyz / worldPosition4f.w + dlightOffset;
for(uint i = 0u; i < 4u; ++i) {
dlighti1 = u_dynamicLightArray[i];
dlighti2 = dlighti1 << 16;
dlight = vec4(ivec4(ivec2(dlighti2.xy), ivec2(dlighti1.xy)) >> 16) * 0.0009765923;
dlight.xyz = dlight.xyz - worldPosition4f.xyz;
blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight);
if(i * 2u + 1u >= u_dynamicLightOffsetCount2i.y) {
break;
}
dlight = vec4(ivec4(ivec2(dlighti2.zw), ivec2(dlighti1.zw)) >> 16) * 0.0009765923;
dlight.xyz = dlight.xyz - worldPosition4f.xyz;
blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight);
if(i * 2u + 2u >= u_dynamicLightOffsetCount2i.y) {
break;
}
}
}
v_dynamicLight1f = blockLight;
#endif
} }

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
client-version-integer=52 client-version-integer=53
client-package-name=net.lax1dude.eaglercraft.v1_8.client client-package-name=net.lax1dude.eaglercraft.v1_8.client
client-origin-name=EaglercraftX client-origin-name=EaglercraftX
client-origin-version=u52 client-origin-version=u53
client-origin-vendor=lax1dude client-origin-vendor=lax1dude
client-fork-name=EaglercraftX client-fork-name=EaglercraftX
client-fork-version=u52 client-fork-version=u53
client-fork-vendor=lax1dude client-fork-vendor=lax1dude

View File

@ -14,10 +14,10 @@ f&1023))}}else d+=String.fromCharCode(f)}return d},ta=a=>{sa||(e.onExit?.(a),O=!
20);const b=w(),d=document.createElement("div");d.setAttribute("style","z-index:100;position:absolute;top:10%;left:10%;right:10%;bottom:10%;background-color:white;border:2px solid #cccccc;overflow-x:hidden;overflow-y:scroll;");d.classList.add("_eaglercraftX_loader_failed_container");a=a?W(a):"";console.error("LoaderMain: [FAILED] "+a);const c=document.createElement("h2");c.style.color="#AA0000";c.style.padding="25px";c.style.fontFamily="sans-serif";c.style.marginBlock="0px";c.appendChild(document.createTextNode(a)); 20);const b=w(),d=document.createElement("div");d.setAttribute("style","z-index:100;position:absolute;top:10%;left:10%;right:10%;bottom:10%;background-color:white;border:2px solid #cccccc;overflow-x:hidden;overflow-y:scroll;");d.classList.add("_eaglercraftX_loader_failed_container");a=a?W(a):"";console.error("LoaderMain: [FAILED] "+a);const c=document.createElement("h2");c.style.color="#AA0000";c.style.padding="25px";c.style.fontFamily="sans-serif";c.style.marginBlock="0px";c.appendChild(document.createTextNode(a));
d.appendChild(c);a=document.createElement("h4");a.style.color="#AA0000";a.style.padding="25px";a.style.fontFamily="sans-serif";a.style.marginBlock="0px";a.appendChild(document.createTextNode("Try again later"));d.appendChild(a);b.appendChild(d)},h:function(a){var b=a>>2;a=v[A[b]];var d=v[A[b+1]];a=a?URL.createObjectURL(new Blob([a],{type:d||"image/png"})):null;b=(b=v[A[b+2]])?U.decode(b):"<h1>Failed to load error screen</h1>";t=v=null;setTimeout(x,20);d=w();var c=document.createElement("img");c.setAttribute("style", d.appendChild(c);a=document.createElement("h4");a.style.color="#AA0000";a.style.padding="25px";a.style.fontFamily="sans-serif";a.style.marginBlock="0px";a.appendChild(document.createTextNode("Try again later"));d.appendChild(a);b.appendChild(d)},h:function(a){var b=a>>2;a=v[A[b]];var d=v[A[b+1]];a=a?URL.createObjectURL(new Blob([a],{type:d||"image/png"})):null;b=(b=v[A[b+2]])?U.decode(b):"<h1>Failed to load error screen</h1>";t=v=null;setTimeout(x,20);d=w();var c=document.createElement("img");c.setAttribute("style",
"z-index:100;position:absolute;top:10px;left:calc(50% - 151px);");c.src=a;d.appendChild(c);a=document.createElement("div");a.setAttribute("style","z-index:100;position:absolute;top:135px;left:10%;right:10%;bottom:50px;background-color:white;border:2px solid #cccccc;");a.classList.add("_eaglercraftX_jspi_unsupported_container");c=document.createElement("iframe");c.classList.add("_eaglercraftX_jspi_unsupported_frame");c.setAttribute("style","border:none;width:100%;height:100%;");c.srcdoc=b;a.appendChild(c); "z-index:100;position:absolute;top:10px;left:calc(50% - 151px);");c.src=a;d.appendChild(c);a=document.createElement("div");a.setAttribute("style","z-index:100;position:absolute;top:135px;left:10%;right:10%;bottom:50px;background-color:white;border:2px solid #cccccc;");a.classList.add("_eaglercraftX_jspi_unsupported_container");c=document.createElement("iframe");c.classList.add("_eaglercraftX_jspi_unsupported_frame");c.setAttribute("style","border:none;width:100%;height:100%;");c.srcdoc=b;a.appendChild(c);
d.appendChild(a)},m:function(a){a>>=2;const b=URL.createObjectURL(new Blob([v[A[a]]],{type:"text/javascript;charset=utf-8"})),d=URL.createObjectURL(new Blob([v[A[a+1]]],{type:"application/wasm"})),c=URL.createObjectURL(new Blob([v[A[a+2]]],{type:"application/octet-stream"})),f=URL.createObjectURL(new Blob([v[A[a+3]]],{type:"application/wasm"})),u=URL.createObjectURL(new Blob([v[A[a+4]]],{type:v[A[a+5]]})),m=URL.createObjectURL(new Blob([v[A[a+6]]],{type:v[A[a+7]]})),V=URL.createObjectURL(new Blob([v[A[a+ d.appendChild(a)},m:function(a){a>>=2;const b=URL.createObjectURL(new Blob([v[A[a]]],{type:"text/javascript;charset=utf-8"})),d=URL.createObjectURL(new Blob([v[A[a+1]]],{type:"application/wasm"})),c=-1!==A[a+2]?URL.createObjectURL(new Blob([v[A[a+2]]],{type:"application/octet-stream"})):null,f=-1!==A[a+3]?URL.createObjectURL(new Blob([v[A[a+3]]],{type:"application/wasm"})):null,u=URL.createObjectURL(new Blob([v[A[a+4]]],{type:v[A[a+5]]})),m=URL.createObjectURL(new Blob([v[A[a+6]]],{type:v[A[a+7]]})),
8]]],{type:v[A[a+9]]})),I=A[a+10],q=Array(I);for(var h=0,l;h<I;++h)l=a+11+3*h,q[h]={data:v[A[l]],name:v[A[l+1]],path:v[A[l+2]]};t=v=null;setTimeout(x,20);window.__eaglercraftXLoaderContext={getEaglercraftXOpts:function(){return ca},getEagRuntimeJSURL:function(){return b},getClassesWASMURL:function(){return d},getClassesDeobfWASMURL:function(){return f},getClassesTEADBGURL:function(){return c},getEPKFiles:function(){return q},getRootElement:function(){return r},getMainArgs:function(){return[]},getImageURL:function(p){switch(p){case 0:return da; V=URL.createObjectURL(new Blob([v[A[a+8]]],{type:v[A[a+9]]})),I=A[a+10],q=Array(I);for(var h=0,l;h<I;++h)l=a+11+3*h,q[h]={data:v[A[l]],name:v[A[l+1]],path:v[A[l+2]]};t=v=null;setTimeout(x,20);window.__eaglercraftXLoaderContext={getEaglercraftXOpts:function(){return ca},getEagRuntimeJSURL:function(){return b},getClassesWASMURL:function(){return d},getClassesDeobfWASMURL:function(){return f},getClassesTEADBGURL:function(){return c},getEPKFiles:function(){return q},getRootElement:function(){return r},
case 1:return u;case 2:return m;case 3:return V;default:return null}},runMain:function(p){setTimeout(p,10)}};a=document.createElement("script");a.type="text/javascript";a.src=b;document.head.appendChild(a)}},X=function(){function a(d){X=d.exports;y=X.o;fa();ia.unshift(X.p);P--;e.monitorRunDependencies?.(P);0==P&&(null!==Q&&(clearInterval(Q),Q=null),R&&(d=R,R=null,d()));return X}P++;e.monitorRunDependencies?.(P);var b={a:ua};if(e.instantiateWasm)try{return e.instantiateWasm(b,a)}catch(d){return M(`Module.instantiateWasm callback failed with error: ${d}`), getMainArgs:function(){return[]},getImageURL:function(p){switch(p){case 0:return da;case 1:return u;case 2:return m;case 3:return V;default:return null}},runMain:function(p){setTimeout(p,10)}};a=document.createElement("script");a.type="text/javascript";a.src=b;document.head.appendChild(a)}},X=function(){function a(d){X=d.exports;y=X.o;fa();ia.unshift(X.p);P--;e.monitorRunDependencies?.(P);0==P&&(null!==Q&&(clearInterval(Q),Q=null),R&&(d=R,R=null,d()));return X}P++;e.monitorRunDependencies?.(P);var b=
!1}S??=ma("loader.wasm")?"loader.wasm":e.locateFile?e.locateFile("loader.wasm",G):G+"loader.wasm";qa(b,function(d){a(d.instance)});return{}}(),va=e._main=(a,b)=>(va=e._main=X.q)(a,b),Y=a=>(Y=X.s)(a),Z;R=function wa(){Z||xa();Z||(R=wa)}; {a:ua};if(e.instantiateWasm)try{return e.instantiateWasm(b,a)}catch(d){return M(`Module.instantiateWasm callback failed with error: ${d}`),!1}S??=ma("loader.wasm")?"loader.wasm":e.locateFile?e.locateFile("loader.wasm",G):G+"loader.wasm";qa(b,function(d){a(d.instance)});return{}}(),va=e._main=(a,b)=>(va=e._main=X.q)(a,b),Y=a=>(Y=X.s)(a),Z;R=function wa(){Z||xa();Z||(R=wa)};
function ya(a=[]){var b=va;a.unshift(E);var d=a.length,c=Y(4*(d+1)),f=c;a.forEach(m=>{for(var V=B,I=f>>2,q=0,h=0;h<m.length;++h){var l=m.charCodeAt(h);127>=l?q++:2047>=l?q+=2:55296<=l&&57343>=l?(q+=4,++h):q+=3}var p=q+1;h=q=Y(p);l=z;if(0<p){p=h+p-1;for(var K=0;K<m.length;++K){var n=m.charCodeAt(K);if(55296<=n&&57343>=n){var Aa=m.charCodeAt(++K);n=65536+((n&1023)<<10)|Aa&1023}if(127>=n){if(h>=p)break;l[h++]=n}else{if(2047>=n){if(h+1>=p)break;l[h++]=192|n>>6}else{if(65535>=n){if(h+2>=p)break;l[h++]= function ya(a=[]){var b=va;a.unshift(E);var d=a.length,c=Y(4*(d+1)),f=c;a.forEach(m=>{for(var V=B,I=f>>2,q=0,h=0;h<m.length;++h){var l=m.charCodeAt(h);127>=l?q++:2047>=l?q+=2:55296<=l&&57343>=l?(q+=4,++h):q+=3}var p=q+1;h=q=Y(p);l=z;if(0<p){p=h+p-1;for(var K=0;K<m.length;++K){var n=m.charCodeAt(K);if(55296<=n&&57343>=n){var Aa=m.charCodeAt(++K);n=65536+((n&1023)<<10)|Aa&1023}if(127>=n){if(h>=p)break;l[h++]=n}else{if(2047>=n){if(h+1>=p)break;l[h++]=192|n>>6}else{if(65535>=n){if(h+2>=p)break;l[h++]=
224|n>>12}else{if(h+3>=p)break;l[h++]=240|n>>18;l[h++]=128|n>>12&63}l[h++]=128|n>>6&63}l[h++]=128|n&63}}l[h]=0}V[I]=q;f+=4});B[f>>2]=0;try{var u=b(d,c);ta(u)}catch(m){m instanceof ra||"unwind"==m||F(1,m)}} 224|n>>12}else{if(h+3>=p)break;l[h++]=240|n>>18;l[h++]=128|n>>12&63}l[h++]=128|n>>6&63}l[h++]=128|n&63}}l[h]=0}V[I]=q;f+=4});B[f>>2]=0;try{var u=b(d,c);ta(u)}catch(m){m instanceof ra||"unwind"==m||F(1,m)}}
function xa(){var a=D;function b(){if(!Z&&(Z=!0,e.calledRun=!0,!O)){T(ia);T(ja);e.onRuntimeInitialized?.();za&&ya(a);if(e.postRun)for("function"==typeof e.postRun&&(e.postRun=[e.postRun]);e.postRun.length;){var d=e.postRun.shift();ka.unshift(d)}T(ka)}}if(!(0<P)){if(e.preRun)for("function"==typeof e.preRun&&(e.preRun=[e.preRun]);e.preRun.length;)la();T(ha);0<P||(e.setStatus?(e.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>e.setStatus(""),1);b()},1)):b())}} function xa(){var a=D;function b(){if(!Z&&(Z=!0,e.calledRun=!0,!O)){T(ia);T(ja);e.onRuntimeInitialized?.();za&&ya(a);if(e.postRun)for("function"==typeof e.postRun&&(e.postRun=[e.postRun]);e.postRun.length;){var d=e.postRun.shift();ka.unshift(d)}T(ka)}}if(!(0<P)){if(e.preRun)for("function"==typeof e.preRun&&(e.preRun=[e.preRun]);e.preRun.length;)la();T(ha);0<P||(e.setStatus?(e.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>e.setStatus(""),1);b()},1)):b())}}

View File

@ -63,6 +63,7 @@ public class PlatformAudio {
static AudioBufferSourceNode recDestSilenceNode = null; static AudioBufferSourceNode recDestSilenceNode = null;
static GainNode micRecGain = null; static GainNode micRecGain = null;
static GainNode gameRecGain = null; static GainNode gameRecGain = null;
static HTMLAudioElement silenceElement = null;
private static final Map<String, BrowserAudioResource> soundCache = new HashMap<>(); private static final Map<String, BrowserAudioResource> soundCache = new HashMap<>();
private static final List<BrowserAudioHandle> activeSounds = new LinkedList<>(); private static final List<BrowserAudioHandle> activeSounds = new LinkedList<>();
@ -253,16 +254,33 @@ public class PlatformAudio {
HTMLAudioElement audio = (HTMLAudioElement) PlatformRuntime.doc.createElement("audio"); HTMLAudioElement audio = (HTMLAudioElement) PlatformRuntime.doc.createElement("audio");
audio.getClassList().add("_eaglercraftX_keepalive_hack"); audio.getClassList().add("_eaglercraftX_keepalive_hack");
audio.setAttribute("style", "display:none;"); audio.setAttribute("style", "display:none;");
audio.setAutoplay(true); audio.setAutoplay(false);
audio.setLoop(true); audio.setLoop(true);
audio.addEventListener("seeked", (e) -> {
// NOP, wakes up the browser's event loop
});
audio.addEventListener("canplay", (e) -> {
if (PlatformRuntime.doc != null && silenceElement != null &&
!PlatformInput.getVisibilityState(PlatformRuntime.doc)) {
silenceElement.play();
}
});
HTMLSourceElement source = (HTMLSourceElement) PlatformRuntime.doc.createElement("source"); HTMLSourceElement source = (HTMLSourceElement) PlatformRuntime.doc.createElement("source");
source.setType("audio/wav"); source.setType("audio/wav");
source.setSrc(TeaVMBlobURLManager.registerNewURLByte(silenceFile, "audio/wav").toExternalForm()); source.setSrc(TeaVMBlobURLManager.registerNewURLByte(silenceFile, "audio/wav").toExternalForm());
audio.appendChild(source); audio.appendChild(source);
audio.addEventListener("seeked", (e) -> {
// NOP, wakes up the browser's event loop
});
PlatformRuntime.parent.appendChild(audio); PlatformRuntime.parent.appendChild(audio);
silenceElement = audio;
}
}
}
static void handleVisibilityChange() {
if (silenceElement != null) {
if (!PlatformInput.getVisibilityState(PlatformRuntime.doc)) {
silenceElement.play();
} else {
silenceElement.pause();
} }
} }
} }
@ -607,6 +625,11 @@ public class PlatformAudio {
micRecGain = null; micRecGain = null;
gameRecGain = null; gameRecGain = null;
} }
if(silenceElement != null) {
silenceElement.pause();
silenceElement.delete();
silenceElement = null;
}
} }
} }

View File

@ -103,6 +103,7 @@ public class PlatformInput {
private static EventListener<?> pointerlock = null; private static EventListener<?> pointerlock = null;
private static EventListener<?> pointerlockerr = null; private static EventListener<?> pointerlockerr = null;
private static EventListener<?> fullscreen = null; private static EventListener<?> fullscreen = null;
private static EventListener<?> visibilitychange = null;
private static Map<String,LegacyKeycodeTranslator.LegacyKeycode> keyCodeTranslatorMap = null; private static Map<String,LegacyKeycodeTranslator.LegacyKeycode> keyCodeTranslatorMap = null;
@ -636,6 +637,12 @@ public class PlatformInput {
isWindowFocused = true; isWindowFocused = true;
} }
}); });
win.getDocument().addEventListener("visibilitychange", visibilitychange = new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
PlatformAudio.handleVisibilityChange();
}
});
try { try {
pointerLockSupported = getSupportedPointerLock(win.getDocument()); pointerLockSupported = getSupportedPointerLock(win.getDocument());
@ -865,7 +872,7 @@ public class PlatformInput {
} }
@JSBody(params = { "doc" }, script = "return (typeof doc.visibilityState !== \"string\") || (doc.visibilityState === \"visible\");") @JSBody(params = { "doc" }, script = "return (typeof doc.visibilityState !== \"string\") || (doc.visibilityState === \"visible\");")
private static native boolean getVisibilityState(JSObject doc); static native boolean getVisibilityState(JSObject doc);
@JSBody(params = { "win" }, script = "return (typeof win.devicePixelRatio === \"number\") ? win.devicePixelRatio : 1.0;") @JSBody(params = { "win" }, script = "return (typeof win.devicePixelRatio === \"number\") ? win.devicePixelRatio : 1.0;")
static native double getDevicePixelRatio(Window win); static native double getDevicePixelRatio(Window win);
@ -1513,6 +1520,10 @@ public class PlatformInput {
win.removeEventListener("blur", blur); win.removeEventListener("blur", blur);
blur = null; blur = null;
} }
if(visibilitychange != null) {
win.getDocument().removeEventListener("visibilitychange", blur);
visibilitychange = null;
}
if(wheel != null) { if(wheel != null) {
canvas.removeEventListener("wheel", wheel); canvas.removeEventListener("wheel", wheel);
wheel = null; wheel = null;

View File

@ -600,6 +600,11 @@ public class PlatformOpenGL {
//checkErr("_wglDrawElements(" + mode + ", " + count + ", " + type + ", " + offset + ");"); //checkErr("_wglDrawElements(" + mode + ", " + count + ", " + type + ", " + offset + ");");
} }
public static void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset) {
ctx.drawRangeElements(mode, start, end, count, type, offset);
//checkErr("_wglDrawRangeElements(" + mode + ", " + start + ", " + end + ", " + count + ", " + type + ", " + offset + ");");
}
public static void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instances) { public static void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instances) {
switch(instancingImpl) { switch(instancingImpl) {
case INSTANCE_IMPL_CORE: case INSTANCE_IMPL_CORE:

View File

@ -72,6 +72,8 @@ public interface WebGL2RenderingContext extends WebGLRenderingContext {
void drawElementsInstanced(int p1, int p2, int p3, int p4, int p5); void drawElementsInstanced(int p1, int p2, int p3, int p4, int p5);
void drawRangeElements(int p1, int p2, int p3, int p4, int p5, int p6);
int getUniformBlockIndex(WebGLProgram p1, String p2); int getUniformBlockIndex(WebGLProgram p1, String p2);
void bindBufferRange(int p1, int p2, WebGLBuffer p3, int p4, int p5); void bindBufferRange(int p1, int p2, WebGLBuffer p3, int p4, int p5);

View File

@ -26,6 +26,7 @@ static uint32_t initEPWBinaryCompressedHelper(struct epw_slice_compressed* slice
static uint32_t initEPWBinaryHelper(struct epw_slice* sliceIn, uint32_t epwLen); static uint32_t initEPWBinaryHelper(struct epw_slice* sliceIn, uint32_t epwLen);
static uint32_t initEPWStringHelper(struct epw_slice* sliceIn, uint32_t epwLen); static uint32_t initEPWStringHelper(struct epw_slice* sliceIn, uint32_t epwLen);
#define SLICE_IS_PRESENT(pSlice) (((struct epw_slice_compressed*)(pSlice))->sliceCompressedLength && ((struct epw_slice_compressed*)(pSlice))->sliceDecompressedLength)
#define SLICE_IN_BOUNDS(pSlice, epwLen) (((struct epw_slice*)(pSlice))->sliceOffset + ((struct epw_slice*)(pSlice))->sliceLength <= (epwLen)) #define SLICE_IN_BOUNDS(pSlice, epwLen) (((struct epw_slice*)(pSlice))->sliceOffset + ((struct epw_slice*)(pSlice))->sliceLength <= (epwLen))
// Note: Linux kernel uses 4096 // Note: Linux kernel uses 4096
@ -186,20 +187,28 @@ int main(int argc, char** argv) {
return -1; return -1;
} }
dbgLog("Decompressing classes.wasm.teadbg..."); if(SLICE_IS_PRESENT(&headerPtr->classesDeobfTEADBGData)) {
dbgLog("Decompressing classes.wasm.teadbg...");
result->classesDeobfTEADBGData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfTEADBGData, epwLen);
if(!result->classesDeobfTEADBGData) { result->classesDeobfTEADBGData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfTEADBGData, epwLen);
resultFailed(EPW_INVALID); if(!result->classesDeobfTEADBGData) {
return -1; resultFailed(EPW_INVALID);
return -1;
}
}else {
result->classesDeobfTEADBGData = -1;
} }
dbgLog("Decompressing deobfuscator..."); if(SLICE_IS_PRESENT(&headerPtr->classesDeobfWASMData)) {
dbgLog("Decompressing deobfuscator...");
result->classesDeobfWASMData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfWASMData, epwLen);
if(!result->classesDeobfWASMData) { result->classesDeobfWASMData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfWASMData, epwLen);
resultFailed(EPW_INVALID); if(!result->classesDeobfWASMData) {
return -1; resultFailed(EPW_INVALID);
return -1;
}
}else {
result->classesDeobfWASMData = -1;
} }
result->numEPKs = numEPKs; result->numEPKs = numEPKs;

View File

@ -78,8 +78,8 @@ addToLibrary({
const eagRuntimeJSURL = URL.createObjectURL(new Blob([results[HEAP32[idx]]], { type: "text/javascript;charset=utf-8" })); const eagRuntimeJSURL = URL.createObjectURL(new Blob([results[HEAP32[idx]]], { type: "text/javascript;charset=utf-8" }));
const classesWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 1]]], { type: "application/wasm" })); const classesWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 1]]], { type: "application/wasm" }));
const classesDeobfTEADBGURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" })); const classesDeobfTEADBGURL = HEAP32[idx + 2] !== -1 ? URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" })) : null;
const classesDeobfWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 3]]], { type: "application/wasm" })); const classesDeobfWASMURL = HEAP32[idx + 3] !== -1 ? URL.createObjectURL(new Blob([results[HEAP32[idx + 3]]], { type: "application/wasm" })) : null;
const pressAnyKey = URL.createObjectURL(new Blob([results[HEAP32[idx + 4]]], { type: results[HEAP32[idx + 5]] })); const pressAnyKey = URL.createObjectURL(new Blob([results[HEAP32[idx + 4]]], { type: results[HEAP32[idx + 5]] }));
const crashImg = URL.createObjectURL(new Blob([results[HEAP32[idx + 6]]], { type: results[HEAP32[idx + 7]] })); const crashImg = URL.createObjectURL(new Blob([results[HEAP32[idx + 6]]], { type: results[HEAP32[idx + 7]] }));

View File

@ -22,6 +22,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.teavm.interop.Address;
import org.teavm.interop.Import; import org.teavm.interop.Import;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
@ -41,6 +42,7 @@ import org.teavm.jso.webaudio.PannerNode;
import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.JOrbisAudioBufferDecoder; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.JOrbisAudioBufferDecoder;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter;
@ -100,7 +102,10 @@ public class PlatformAudio {
if (silenceFile != null) { if (silenceFile != null) {
MemoryStack.push(); MemoryStack.push();
try { try {
initKeepAliveHack(WASMGCDirectArrayConverter.byteArrayToStackU8Array(silenceFile)); int len = silenceFile.length;
Address addr = MemoryStack.malloc(len);
WASMGCDirectArrayCopy.memcpy(addr, silenceFile, 0, len);
initKeepAliveHack(addr, len);
}finally { }finally {
MemoryStack.pop(); MemoryStack.pop();
} }
@ -112,7 +117,7 @@ public class PlatformAudio {
private static native AudioContext getContext(); private static native AudioContext getContext();
@Import(module = "platformAudio", name = "initKeepAliveHack") @Import(module = "platformAudio", name = "initKeepAliveHack")
private static native void initKeepAliveHack(Uint8Array array); private static native void initKeepAliveHack(Address addr, int length);
protected static class BrowserAudioResource implements IAudioResource { protected static class BrowserAudioResource implements IAudioResource {

View File

@ -199,7 +199,7 @@ public class PlatformOpenGL {
@Import(module = "platformOpenGL", name = "glReadPixels") @Import(module = "platformOpenGL", name = "glReadPixels")
static native void _wglReadPixelsN(int x, int y, int width, int height, int format, int type, ArrayBufferView array); static native void _wglReadPixelsN(int x, int y, int width, int height, int format, int type, ArrayBufferView array);
@Import(module = "platformOpenGL", name = "glReadPixels0") @Import(module = "platformOpenGL", name = "glReadPixels")
static native void _wglReadPixelsN(int x, int y, int width, int height, int format, int type, ArrayBufferView array, int offset); static native void _wglReadPixelsN(int x, int y, int width, int height, int format, int type, ArrayBufferView array, int offset);
@Import(module = "platformOpenGL", name = "glPolygonOffset") @Import(module = "platformOpenGL", name = "glPolygonOffset")
@ -367,7 +367,7 @@ public class PlatformOpenGL {
@Import(module = "platformOpenGL", name = "glBufferData") @Import(module = "platformOpenGL", name = "glBufferData")
static native void _wglBufferDataN(int target, ArrayBufferView typedArray, int usage); static native void _wglBufferDataN(int target, ArrayBufferView typedArray, int usage);
@Import(module = "platformOpenGL", name = "glBufferData0") @Import(module = "platformOpenGL", name = "glBufferData")
static native void _wglBufferDataN(int target, ArrayBufferView typedArray, int usage, int srcOffset, int length); static native void _wglBufferDataN(int target, ArrayBufferView typedArray, int usage, int srcOffset, int length);
public static void _wglBufferSubData(int target, int dstOffset, ByteBuffer buffer) { public static void _wglBufferSubData(int target, int dstOffset, ByteBuffer buffer) {
@ -397,7 +397,7 @@ public class PlatformOpenGL {
@Import(module = "platformOpenGL", name = "glBufferSubData") @Import(module = "platformOpenGL", name = "glBufferSubData")
static native void _wglBufferSubDataN(int target, int dstOffset, ArrayBufferView typedArray); static native void _wglBufferSubDataN(int target, int dstOffset, ArrayBufferView typedArray);
@Import(module = "platformOpenGL", name = "glBufferSubData0") @Import(module = "platformOpenGL", name = "glBufferSubData")
static native void _wglBufferSubDataN(int target, int dstOffset, ArrayBufferView typedArray, int srcOffset, int length); static native void _wglBufferSubDataN(int target, int dstOffset, ArrayBufferView typedArray, int srcOffset, int length);
public static void _wglBindVertexArray(IVertexArrayGL objId) { public static void _wglBindVertexArray(IVertexArrayGL objId) {
@ -450,7 +450,7 @@ public class PlatformOpenGL {
static native void _wglTexImage3DN(int target, int level, int internalFormat, int width, int height, int depth, static native void _wglTexImage3DN(int target, int level, int internalFormat, int width, int height, int depth,
int border, int format, int type, ArrayBufferView typedArray); int border, int format, int type, ArrayBufferView typedArray);
@Import(module = "platformOpenGL", name = "glTexImage3D0") @Import(module = "platformOpenGL", name = "glTexImage3D")
static native void _wglTexImage3DN(int target, int level, int internalFormat, int width, int height, int depth, static native void _wglTexImage3DN(int target, int level, int internalFormat, int width, int height, int depth,
int border, int format, int type, ArrayBufferView typedArray, int offset); int border, int format, int type, ArrayBufferView typedArray, int offset);
@ -513,7 +513,7 @@ public class PlatformOpenGL {
static native void _wglTexImage2DN(int target, int level, int internalFormat, int width, int height, int border, static native void _wglTexImage2DN(int target, int level, int internalFormat, int width, int height, int border,
int format, int type, ArrayBufferView typedArray); int format, int type, ArrayBufferView typedArray);
@Import(module = "platformOpenGL", name = "glTexImage2D0") @Import(module = "platformOpenGL", name = "glTexImage2D")
static native void _wglTexImage2DN(int target, int level, int internalFormat, int width, int height, int border, static native void _wglTexImage2DN(int target, int level, int internalFormat, int width, int height, int border,
int format, int type, ArrayBufferView typedArray, int offset); int format, int type, ArrayBufferView typedArray, int offset);
@ -565,7 +565,7 @@ public class PlatformOpenGL {
static native void _wglTexSubImage2D(int target, int level, int offsetx, int offsety, int width, int height, static native void _wglTexSubImage2D(int target, int level, int offsetx, int offsety, int width, int height,
int format, int type, ArrayBufferView typedArray); int format, int type, ArrayBufferView typedArray);
@Import(module = "platformOpenGL", name = "glTexSubImage2D0") @Import(module = "platformOpenGL", name = "glTexSubImage2D")
static native void _wglTexSubImage2D(int target, int level, int offsetx, int offsety, int width, int height, static native void _wglTexSubImage2D(int target, int level, int offsetx, int offsety, int width, int height,
int format, int type, ArrayBufferView typedArray, int offset); int format, int type, ArrayBufferView typedArray, int offset);
@ -658,6 +658,9 @@ public class PlatformOpenGL {
@Import(module = "platformOpenGL", name = "glDrawElements") @Import(module = "platformOpenGL", name = "glDrawElements")
public static native void _wglDrawElements(int mode, int count, int type, int offset); public static native void _wglDrawElements(int mode, int count, int type, int offset);
@Import(module = "platformOpenGL", name = "glDrawRangeElements")
public static native void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset);
@Import(module = "platformOpenGL", name = "glDrawArraysInstanced") @Import(module = "platformOpenGL", name = "glDrawArraysInstanced")
public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced); public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced);

View File

@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.teavm.interop.Address;
import org.teavm.interop.Import; import org.teavm.interop.Import;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
@ -32,6 +33,7 @@ import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime.JSEagRuntimeEvent; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime.JSEagRuntimeEvent;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
@ -226,8 +228,10 @@ public class PlatformWebView {
}else if(packet.type == SPacketWebViewMessageV4EAG.TYPE_BINARY) { }else if(packet.type == SPacketWebViewMessageV4EAG.TYPE_BINARY) {
MemoryStack.push(); MemoryStack.push();
try { try {
sendBinaryMessage(BetterJSStringConverter.stringToJS(currentMessageChannelName), int len = packet.data.length;
WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.data)); Address addr = MemoryStack.malloc(len);
WASMGCDirectArrayCopy.memcpy(addr, packet.data, 0, len);
sendBinaryMessage(BetterJSStringConverter.stringToJS(currentMessageChannelName), addr, len);
}finally { }finally {
MemoryStack.pop(); MemoryStack.pop();
} }
@ -241,7 +245,7 @@ public class PlatformWebView {
private static native void sendStringMessage(JSString ch, JSString str); private static native void sendStringMessage(JSString ch, JSString str);
@Import(module = "platformWebView", name = "sendBinaryMessage") @Import(module = "platformWebView", name = "sendBinaryMessage")
private static native void sendBinaryMessage(JSString ch, Uint8Array bin); private static native void sendBinaryMessage(JSString ch, Address addr, int length);
private static void sendMessageToServer(String channelName, int type, byte[] data) { private static void sendMessageToServer(String channelName, int type, byte[] data) {
if(channelName.length() > 255) { if(channelName.length() > 255) {

View File

@ -16,6 +16,7 @@
package net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm; package net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm;
import org.teavm.interop.Address;
import org.teavm.interop.Import; import org.teavm.interop.Import;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty; import org.teavm.jso.JSProperty;
@ -124,16 +125,14 @@ public class IndexedDBFilesystem implements IEaglerFilesystem {
@Override @Override
public void eaglerWrite(String pathName, ByteBuffer data) { public void eaglerWrite(String pathName, ByteBuffer data) {
int len = data.remaining(); if(!eaglerWrite(database, BetterJSStringConverter.stringToJS(pathName),
Uint8Array arr = new Uint8Array(len); WASMGCBufferAllocator.getByteBufferAddress(data), data.remaining())) {
arr.set(WASMGCBufferAllocator.getByteBufferView(data)); throw new EaglerFileSystemException("Failed to write " + data.remaining() + " byte file to indexeddb table: " + pathName);
if(!eaglerWrite(database, BetterJSStringConverter.stringToJS(pathName), arr.getBuffer())) {
throw new EaglerFileSystemException("Failed to write " + len + " byte file to indexeddb table: " + pathName);
} }
} }
@Import(module = "platformFilesystem", name = "eaglerWrite") @Import(module = "platformFilesystem", name = "eaglerWrite")
private static native boolean eaglerWrite(IDBDatabase database, JSString pathName, ArrayBuffer arr); private static native boolean eaglerWrite(IDBDatabase database, JSString pathName, Address addr, int length);
@Override @Override
public boolean eaglerExists(String pathName) { public boolean eaglerExists(String pathName) {

View File

@ -21,7 +21,6 @@ import java.util.List;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty; import org.teavm.jso.JSProperty;
import org.teavm.jso.core.JSString;
import org.teavm.jso.typedarrays.Uint8Array; import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.EagUtils; import net.lax1dude.eaglercraft.v1_8.EagUtils;

View File

@ -21,14 +21,14 @@ import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.teavm.interop.Address;
import org.teavm.interop.Import; import org.teavm.interop.Import;
import org.teavm.jso.core.JSString; import org.teavm.jso.core.JSString;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData; import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
@ -71,8 +71,10 @@ public class ClientPlatformSingleplayer {
}else { }else {
MemoryStack.push(); MemoryStack.push();
try { try {
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), int len = packet.contents.length;
WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.contents)); Address addr = MemoryStack.malloc(len);
WASMGCDirectArrayCopy.memcpy(addr, packet.contents, 0, len);
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), addr, len);
} finally { } finally {
MemoryStack.pop(); MemoryStack.pop();
} }
@ -80,7 +82,7 @@ public class ClientPlatformSingleplayer {
} }
@Import(module = "clientPlatformSingleplayer", name = "sendPacket") @Import(module = "clientPlatformSingleplayer", name = "sendPacket")
private static native void sendPacket0(JSString channel, Uint8Array arr); private static native void sendPacket0(JSString channel, Address addr, int length);
public static List<IPCPacketData> recieveAllPacket() { public static List<IPCPacketData> recieveAllPacket() {
if(isSingleThreadMode) { if(isSingleThreadMode) {

View File

@ -22,11 +22,11 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.teavm.interop.Address;
import org.teavm.interop.Import; import org.teavm.interop.Import;
import org.teavm.jso.JSFunctor; import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import org.teavm.jso.core.JSString; import org.teavm.jso.core.JSString;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.Filesystem; import net.lax1dude.eaglercraft.v1_8.Filesystem;
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter; import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter;
@ -34,7 +34,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.IEaglerFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData; import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy;
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFile2; import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFile2;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter;
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter;
@ -74,8 +74,10 @@ public class ServerPlatformSingleplayer {
}else { }else {
MemoryStack.push(); MemoryStack.push();
try { try {
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), int len = packet.contents.length;
WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.contents)); Address addr = MemoryStack.malloc(len);
WASMGCDirectArrayCopy.memcpy(addr, packet.contents, 0, len);
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), addr, len);
} finally { } finally {
MemoryStack.pop(); MemoryStack.pop();
} }
@ -83,7 +85,7 @@ public class ServerPlatformSingleplayer {
} }
@Import(module = "serverPlatformSingleplayer", name = "sendPacket") @Import(module = "serverPlatformSingleplayer", name = "sendPacket")
private static native void sendPacket0(JSString channel, Uint8Array arr); private static native void sendPacket0(JSString channel, Address addr, int length);
public static List<IPCPacketData> recieveAllPacket() { public static List<IPCPacketData> recieveAllPacket() {
if(singleThreadMode) { if(singleThreadMode) {

View File

@ -100,8 +100,13 @@ function initializeClientPlatfSP(spImports) {
}); });
})); }));
const classesTEADBGCopy = new Int8Array(classesTEADBG.length); const transferList = [];
classesTEADBGCopy.set(classesTEADBG, 0); var classesTEADBGCopy = null;
if(classesTEADBG) {
classesTEADBGCopy = classesTEADBG.buffer.slice(classesTEADBG.byteOffset, classesTEADBG.byteOffset + classesTEADBG.byteLength);
transferList.push(classesTEADBGCopy);
}
var eagRuntimeJS; var eagRuntimeJS;
try { try {
@ -116,13 +121,15 @@ function initializeClientPlatfSP(spImports) {
return false; return false;
} }
transferList.push(eagRuntimeJS);
workerObj.postMessage({ workerObj.postMessage({
"eaglercraftXOpts": eaglercraftXOpts, "eaglercraftXOpts": eaglercraftXOpts,
"eagruntimeJS": eagRuntimeJS, "eagruntimeJS": eagRuntimeJS,
"classesWASM": classesWASMModule, "classesWASM": classesWASMModule,
"classesDeobfWASM": classesDeobfWASMModule, "classesDeobfWASM": classesDeobfWASMModule,
"classesTEADBG": classesTEADBGCopy.buffer "classesTEADBG": classesTEADBGCopy
}); }, transferList);
return true; return true;
}; };
@ -131,16 +138,16 @@ function initializeClientPlatfSP(spImports) {
/** /**
* @param {string} channel * @param {string} channel
* @param {Uint8Array} arr * @param {number} addr
* @param {number} length
*/ */
spImports["sendPacket"] = function(channel, arr) { spImports["sendPacket"] = function(channel, addr, length) {
if(workerObj) { if(workerObj) {
const copiedArray = new Uint8Array(arr.length); const copiedArray = heapArrayBuffer.slice(addr, addr + length);
copiedArray.set(arr, 0);
workerObj.postMessage({ workerObj.postMessage({
"ch": channel, "ch": channel,
"dat": copiedArray.buffer "dat": copiedArray
}, [copiedArray.buffer]); }, [copiedArray]);
} }
}; };

View File

@ -45,7 +45,7 @@ async function entryPoint() {
const teavm = await wasmGC.load(classesWASM, { const teavm = await wasmGC.load(classesWASM, {
stackDeobfuscator: { stackDeobfuscator: {
enabled: true, enabled: !!(classesDeobfWASM && classesTEADBGURL),
path: classesDeobfWASM, path: classesDeobfWASM,
infoLocation: "external", infoLocation: "external",
externalInfoPath: classesTEADBGURL externalInfoPath: classesTEADBGURL

View File

@ -106,6 +106,8 @@ var keepAliveCallback = null;
var showDebugConsole = null; var showDebugConsole = null;
/** @type {function()|null} */ /** @type {function()|null} */
var resetSettings = null; var resetSettings = null;
/** @type {function()|null} */
var handleVisibilityChange = null;
const runtimeOpts = { const runtimeOpts = {
localStorageNamespace: "_eaglercraftX", localStorageNamespace: "_eaglercraftX",

View File

@ -16,6 +16,9 @@
const platfAudioName = "platformAudio"; const platfAudioName = "platformAudio";
/** @type {HTMLAudioElement|null} */
var silenceElement = null;
function setCurrentAudioContext(audioContext, audioImports) { function setCurrentAudioContext(audioContext, audioImports) {
/** /**
@ -26,25 +29,41 @@ function setCurrentAudioContext(audioContext, audioImports) {
}; };
/** /**
* @param {Uint8Array} fileData * @param {number} addr
* @param {number} length
*/ */
audioImports["initKeepAliveHack"] = function(fileData) { audioImports["initKeepAliveHack"] = function(addr, length) {
const copiedData = new Uint8Array(fileData.length); const copiedData = heapArrayBuffer.slice(addr, addr + length);
copiedData.set(fileData, 0);
const copiedDataURI = URL.createObjectURL(new Blob([copiedData], {type: "audio/wav"})); const copiedDataURI = URL.createObjectURL(new Blob([copiedData], {type: "audio/wav"}));
const audioElement = /** @type {HTMLAudioElement} */ (document.createElement("audio")); const audioElement = /** @type {HTMLAudioElement} */ (document.createElement("audio"));
audioElement.classList.add("_eaglercraftX_keepalive_hack"); audioElement.classList.add("_eaglercraftX_keepalive_hack");
audioElement.setAttribute("style", "display:none;"); audioElement.setAttribute("style", "display:none;");
audioElement.autoplay = true; audioElement.autoplay = false;
audioElement.loop = true; audioElement.loop = true;
audioElement.addEventListener("seeked", function() {
// NOP, wakes up the browser's event loop
});
audioElement.addEventListener("canplay", function() {
if (silenceElement && document.visibilityState === "hidden") {
silenceElement.play();
}
});
const sourceElement = /** @type {HTMLSourceElement} */ (document.createElement("source")); const sourceElement = /** @type {HTMLSourceElement} */ (document.createElement("source"));
sourceElement.type = "audio/wav"; sourceElement.type = "audio/wav";
sourceElement.src = copiedDataURI; sourceElement.src = copiedDataURI;
audioElement.appendChild(sourceElement); audioElement.appendChild(sourceElement);
audioElement.addEventListener("seeked", function() {
// NOP, wakes up the browser's event loop
});
parentElement.appendChild(audioElement); parentElement.appendChild(audioElement);
silenceElement = audioElement;
};
handleVisibilityChange = function() {
if (silenceElement) {
if (document.visibilityState === "hidden") {
silenceElement.play();
} else {
silenceElement.pause();
}
}
}; };
/** /**

View File

@ -144,13 +144,24 @@ function eaglerReadImpl(database, pathName) {
eagruntimeImpl.platformFilesystem["eaglerRead"] = new WebAssembly.Suspending(eaglerReadImpl); eagruntimeImpl.platformFilesystem["eaglerRead"] = new WebAssembly.Suspending(eaglerReadImpl);
/**
* @param {IDBDatabase} database
* @param {string} pathName
* @param {number} addr
* @param {number} length
* @return {Promise}
*/
function eaglerWriteImpl(database, pathName, addr, length) {
return eaglerWriteImpl0(database, pathName, heapArrayBuffer.slice(addr, addr + length));
}
/** /**
* @param {IDBDatabase} database * @param {IDBDatabase} database
* @param {string} pathName * @param {string} pathName
* @param {ArrayBuffer} arr * @param {ArrayBuffer} arr
* @return {Promise} * @return {Promise}
*/ */
function eaglerWriteImpl(database, pathName, arr) { function eaglerWriteImpl0(database, pathName, arr) {
return new Promise(function(resolve) { return new Promise(function(resolve) {
const tx = database.transaction("filesystem", "readwrite"); const tx = database.transaction("filesystem", "readwrite");
const r = tx.objectStore("filesystem").put(writeDBRow(pathName, arr)); const r = tx.objectStore("filesystem").put(writeDBRow(pathName, arr));
@ -193,7 +204,7 @@ eagruntimeImpl.platformFilesystem["eaglerExists"] = new WebAssembly.Suspending(e
*/ */
async function eaglerMoveImpl(database, pathNameOld, pathNameNew) { async function eaglerMoveImpl(database, pathNameOld, pathNameNew) {
const oldData = await eaglerReadImpl(database, pathNameOld); const oldData = await eaglerReadImpl(database, pathNameOld);
if(!oldData || !(await eaglerWriteImpl(database, pathNameNew, oldData))) { if(!oldData || !(await eaglerWriteImpl0(database, pathNameNew, oldData))) {
return false; return false;
} }
return await eaglerDeleteImpl(database, pathNameOld); return await eaglerDeleteImpl(database, pathNameOld);
@ -209,7 +220,7 @@ eagruntimeImpl.platformFilesystem["eaglerMove"] = new WebAssembly.Suspending(eag
*/ */
async function eaglerCopyImpl(database, pathNameOld, pathNameNew) { async function eaglerCopyImpl(database, pathNameOld, pathNameNew) {
const oldData = await eaglerReadImpl(database, pathNameOld); const oldData = await eaglerReadImpl(database, pathNameOld);
return oldData && (await eaglerWriteImpl(database, pathNameNew, oldData)); return oldData && (await eaglerWriteImpl0(database, pathNameNew, oldData));
} }
eagruntimeImpl.platformFilesystem["eaglerCopy"] = new WebAssembly.Suspending(eaglerCopyImpl); eagruntimeImpl.platformFilesystem["eaglerCopy"] = new WebAssembly.Suspending(eaglerCopyImpl);

View File

@ -118,7 +118,8 @@ async function initPlatformInput(inputImports) {
blur: null, blur: null,
pointerlock: null, pointerlock: null,
pointerlockerr: null, pointerlockerr: null,
fullscreenChange: null fullscreenChange: null,
visibilitychange: null
}; };
touchKeyboardOpenZone = document.createElement("div"); touchKeyboardOpenZone = document.createElement("div");
@ -351,6 +352,11 @@ async function initPlatformInput(inputImports) {
pushEvent(EVENT_TYPE_INPUT, EVENT_INPUT_FOCUS, null); pushEvent(EVENT_TYPE_INPUT, EVENT_INPUT_FOCUS, null);
}); });
document.addEventListener("visibilitychange", currentEventListeners.visibilitychange = function(/** Event */ evt) {
if (handleVisibilityChange)
handleVisibilityChange();
});
/** /**
* @param {number} evtType * @param {number} evtType
* @param {KeyboardEvent} evt * @param {KeyboardEvent} evt
@ -1138,6 +1144,10 @@ async function initPlatformInput(inputImports) {
window.removeEventListener("blur", /** @type {function(Event)} */ (currentEventListeners.blur)); window.removeEventListener("blur", /** @type {function(Event)} */ (currentEventListeners.blur));
currentEventListeners.blur = null; currentEventListeners.blur = null;
} }
if(currentEventListeners.visibilitychange) {
document.removeEventListener("visibilitychange", currentEventListeners.visibilitychange);
currentEventListeners.visibilitychange = null;
}
if(currentEventListeners.pointerlock) { if(currentEventListeners.pointerlock) {
document.removeEventListener("pointerlockchange", /** @type {function(Event)} */ (currentEventListeners.pointerlock)); document.removeEventListener("pointerlockchange", /** @type {function(Event)} */ (currentEventListeners.pointerlock));
currentEventListeners.pointerlock = null; currentEventListeners.pointerlock = null;

View File

@ -99,7 +99,7 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) {
glImports["glColorMask"] = ctx.colorMask.bind(ctx); glImports["glColorMask"] = ctx.colorMask.bind(ctx);
glImports["glDrawBuffers"] = glesVersIn >= 300 ? ctx.drawBuffers.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDrawBuffers"); glImports["glDrawBuffers"] = glesVersIn >= 300 ? ctx.drawBuffers.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDrawBuffers");
glImports["glReadBuffer"] = glesVersIn >= 300 ? ctx.readBuffer.bind(ctx) : unsupportedFunc(platfOpenGLName, "glReadBuffer"); glImports["glReadBuffer"] = glesVersIn >= 300 ? ctx.readBuffer.bind(ctx) : unsupportedFunc(platfOpenGLName, "glReadBuffer");
glImports["glReadPixels"] = glImports["glReadPixels0"] = ctx.readPixels.bind(ctx); glImports["glReadPixels"] = ctx.readPixels.bind(ctx);
glImports["glPolygonOffset"] = ctx.polygonOffset.bind(ctx); glImports["glPolygonOffset"] = ctx.polygonOffset.bind(ctx);
glImports["glLineWidth"] = ctx.lineWidth.bind(ctx); glImports["glLineWidth"] = ctx.lineWidth.bind(ctx);
glImports["glGenBuffers"] = ctx.createBuffer.bind(ctx); glImports["glGenBuffers"] = ctx.createBuffer.bind(ctx);
@ -117,8 +117,8 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) {
glImports["glDeleteRenderbuffer"] = ctx.deleteRenderbuffer.bind(ctx); glImports["glDeleteRenderbuffer"] = ctx.deleteRenderbuffer.bind(ctx);
glImports["glDeleteQueries"] = glesVersIn >= 300 ? ctx.deleteQuery.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDeleteQueries"); glImports["glDeleteQueries"] = glesVersIn >= 300 ? ctx.deleteQuery.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDeleteQueries");
glImports["glBindBuffer"] = ctx.bindBuffer.bind(ctx); glImports["glBindBuffer"] = ctx.bindBuffer.bind(ctx);
glImports["glBufferData"] = glImports["glBufferData0"] = ctx.bufferData.bind(ctx); glImports["glBufferData"] = ctx.bufferData.bind(ctx);
glImports["glBufferSubData"] = glImports["glBufferSubData0"] = ctx.bufferSubData.bind(ctx); glImports["glBufferSubData"] = ctx.bufferSubData.bind(ctx);
glImports["glEnableVertexAttribArray"] = ctx.enableVertexAttribArray.bind(ctx); glImports["glEnableVertexAttribArray"] = ctx.enableVertexAttribArray.bind(ctx);
glImports["glDisableVertexAttribArray"] = ctx.disableVertexAttribArray.bind(ctx); glImports["glDisableVertexAttribArray"] = ctx.disableVertexAttribArray.bind(ctx);
glImports["glVertexAttribPointer"] = ctx.vertexAttribPointer.bind(ctx); glImports["glVertexAttribPointer"] = ctx.vertexAttribPointer.bind(ctx);
@ -126,9 +126,9 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) {
glImports["glBindTexture"] = ctx.bindTexture.bind(ctx); glImports["glBindTexture"] = ctx.bindTexture.bind(ctx);
glImports["glTexParameterf"] = ctx.texParameterf.bind(ctx); glImports["glTexParameterf"] = ctx.texParameterf.bind(ctx);
glImports["glTexParameteri"] = ctx.texParameteri.bind(ctx); glImports["glTexParameteri"] = ctx.texParameteri.bind(ctx);
glImports["glTexImage3D"] = glImports["glTexImage3D0"] = glesVersIn >= 300 ? ctx.texImage3D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexImage3D"); glImports["glTexImage3D"] = glesVersIn >= 300 ? ctx.texImage3D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexImage3D");
glImports["glTexImage2D"] = glImports["glTexImage2D0"] = ctx.texImage2D.bind(ctx); glImports["glTexImage2D"] = ctx.texImage2D.bind(ctx);
glImports["glTexSubImage2D"] = glImports["glTexSubImage2D0"] = ctx.texSubImage2D.bind(ctx); glImports["glTexSubImage2D"] = ctx.texSubImage2D.bind(ctx);
glImports["glCopyTexSubImage2D"] = ctx.copyTexSubImage2D.bind(ctx); glImports["glCopyTexSubImage2D"] = ctx.copyTexSubImage2D.bind(ctx);
glImports["glTexStorage2D"] = glesVersIn >= 300 ? ctx.texStorage2D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexStorage2D"); glImports["glTexStorage2D"] = glesVersIn >= 300 ? ctx.texStorage2D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexStorage2D");
glImports["glPixelStorei"] = ctx.pixelStorei.bind(ctx); glImports["glPixelStorei"] = ctx.pixelStorei.bind(ctx);
@ -145,6 +145,7 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) {
glImports["glGetProgramInfoLog"] = ctx.getProgramInfoLog.bind(ctx); glImports["glGetProgramInfoLog"] = ctx.getProgramInfoLog.bind(ctx);
glImports["glDrawArrays"] = ctx.drawArrays.bind(ctx); glImports["glDrawArrays"] = ctx.drawArrays.bind(ctx);
glImports["glDrawElements"] = ctx.drawElements.bind(ctx); glImports["glDrawElements"] = ctx.drawElements.bind(ctx);
glImports["glDrawRangeElements"] = glesVersIn >= 300 ? ctx.drawRangeElements.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDrawRangeElements");
glImports["glBindAttribLocation"] = ctx.bindAttribLocation.bind(ctx); glImports["glBindAttribLocation"] = ctx.bindAttribLocation.bind(ctx);
glImports["glGetAttribLocation"] = ctx.getAttribLocation.bind(ctx); glImports["glGetAttribLocation"] = ctx.getAttribLocation.bind(ctx);
glImports["glGetUniformLocation"] = ctx.getUniformLocation.bind(ctx); glImports["glGetUniformLocation"] = ctx.getUniformLocation.bind(ctx);
@ -299,7 +300,6 @@ function setNoGLContext(glImports) {
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawBuffers"); setUnsupportedFunc(glImports, platfOpenGLName, "glDrawBuffers");
setUnsupportedFunc(glImports, platfOpenGLName, "glReadBuffer"); setUnsupportedFunc(glImports, platfOpenGLName, "glReadBuffer");
setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels"); setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels");
setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels0");
setUnsupportedFunc(glImports, platfOpenGLName, "glPolygonOffset"); setUnsupportedFunc(glImports, platfOpenGLName, "glPolygonOffset");
setUnsupportedFunc(glImports, platfOpenGLName, "glLineWidth"); setUnsupportedFunc(glImports, platfOpenGLName, "glLineWidth");
setUnsupportedFunc(glImports, platfOpenGLName, "glGenBuffers"); setUnsupportedFunc(glImports, platfOpenGLName, "glGenBuffers");
@ -318,9 +318,7 @@ function setNoGLContext(glImports) {
setUnsupportedFunc(glImports, platfOpenGLName, "glDeleteQueries"); setUnsupportedFunc(glImports, platfOpenGLName, "glDeleteQueries");
setUnsupportedFunc(glImports, platfOpenGLName, "glBindBuffer"); setUnsupportedFunc(glImports, platfOpenGLName, "glBindBuffer");
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData"); setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData");
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData0");
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData"); setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData");
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData0");
setUnsupportedFunc(glImports, platfOpenGLName, "glEnableVertexAttribArray"); setUnsupportedFunc(glImports, platfOpenGLName, "glEnableVertexAttribArray");
setUnsupportedFunc(glImports, platfOpenGLName, "glDisableVertexAttribArray"); setUnsupportedFunc(glImports, platfOpenGLName, "glDisableVertexAttribArray");
setUnsupportedFunc(glImports, platfOpenGLName, "glVertexAttribPointer"); setUnsupportedFunc(glImports, platfOpenGLName, "glVertexAttribPointer");
@ -329,11 +327,8 @@ function setNoGLContext(glImports) {
setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameterf"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameterf");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameteri"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameteri");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D0");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D0");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D0");
setUnsupportedFunc(glImports, platfOpenGLName, "glCopyTexSubImage2D"); setUnsupportedFunc(glImports, platfOpenGLName, "glCopyTexSubImage2D");
setUnsupportedFunc(glImports, platfOpenGLName, "glTexStorage2D"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexStorage2D");
setUnsupportedFunc(glImports, platfOpenGLName, "glPixelStorei"); setUnsupportedFunc(glImports, platfOpenGLName, "glPixelStorei");
@ -350,6 +345,7 @@ function setNoGLContext(glImports) {
setUnsupportedFunc(glImports, platfOpenGLName, "glGetProgramInfoLog"); setUnsupportedFunc(glImports, platfOpenGLName, "glGetProgramInfoLog");
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawArrays"); setUnsupportedFunc(glImports, platfOpenGLName, "glDrawArrays");
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawElements"); setUnsupportedFunc(glImports, platfOpenGLName, "glDrawElements");
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawRangeElements");
setUnsupportedFunc(glImports, platfOpenGLName, "glBindAttribLocation"); setUnsupportedFunc(glImports, platfOpenGLName, "glBindAttribLocation");
setUnsupportedFunc(glImports, platfOpenGLName, "glGetAttribLocation"); setUnsupportedFunc(glImports, platfOpenGLName, "glGetAttribLocation");
setUnsupportedFunc(glImports, platfOpenGLName, "glGetUniformLocation"); setUnsupportedFunc(glImports, platfOpenGLName, "glGetUniformLocation");

View File

@ -121,19 +121,18 @@ function initializePlatfWebView(webViewImports) {
/** /**
* @param {string} ch * @param {string} ch
* @param {Uint8Array} bin * @param {number} addr
* @param {number} length
*/ */
webViewImports["sendBinaryMessage"] = function(ch, bin) { webViewImports["sendBinaryMessage"] = function(ch, addr, length) {
try { try {
var w; var w;
if(currentIFrame != null && (w = currentIFrame.contentWindow) != null) { if(currentIFrame != null && (w = currentIFrame.contentWindow) != null) {
const copiedArray = new Uint8Array(bin.length);
copiedArray.set(bin, 0);
w.postMessage({ w.postMessage({
"ver": 1, "ver": 1,
"channel": ch, "channel": ch,
"type": "binary", "type": "binary",
"data": copiedArray.buffer "data": heapArrayBuffer.slice(addr, addr + length)
}, "*"); }, "*");
}else { }else {
eagError("Server tried to send the WebView a message, but the message channel is not open!"); eagError("Server tried to send the WebView a message, but the message channel is not open!");

View File

@ -57,15 +57,15 @@ function initializeServerPlatfSP(spImports) {
/** /**
* @param {string} channel * @param {string} channel
* @param {Uint8Array} arr * @param {number} addr
* @param {number} length
*/ */
spImports["sendPacket"] = function(channel, arr) { spImports["sendPacket"] = function(channel, addr, length) {
const copiedArray = new Uint8Array(arr.length); const copiedArray = heapArrayBuffer.slice(addr, addr + length);
copiedArray.set(arr, 0);
postMessage({ postMessage({
"ch": channel, "ch": channel,
"dat": copiedArray.buffer "dat": copiedArray
}, [copiedArray.buffer]); }, [copiedArray]);
}; };
spImports["getAvailablePackets"] = serverMessageQueue.getLength.bind(serverMessageQueue); spImports["getAvailablePackets"] = serverMessageQueue.getLength.bind(serverMessageQueue);