mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-07-13 10:59:57 -05:00
Update #53 - Improved FPS, reduced WebGL context loss crashes
This commit is contained in:
@ -1 +1 @@
|
||||
u52
|
||||
u53
|
@ -598,7 +598,7 @@
|
||||
~ GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight);
|
||||
~ GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
> DELETE 2 @ 2 : 4
|
||||
> DELETE 1 @ 1 : 4
|
||||
|
||||
> DELETE 5 @ 5 : 6
|
||||
|
||||
|
@ -5,13 +5,12 @@
|
||||
# Version: 1.0
|
||||
# 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.VertexFormat;
|
||||
+ 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.dynamiclights.DynamicLightsStateManager;
|
||||
|
||||
> DELETE 4 @ 4 : 5
|
||||
|
||||
|
@ -89,7 +89,17 @@
|
||||
~ 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();
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
~ eaglercraft.resourcePack.load.loading=Loading 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.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.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.desc.0=Renders chromatic abberation and lens distorion
|
||||
|
@ -573,6 +573,10 @@ public class PlatformOpenGL {
|
||||
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) {
|
||||
switch(instancingImpl) {
|
||||
case INSTANCE_IMPL_CORE:
|
||||
|
@ -10,7 +10,7 @@ public class EaglercraftVersion {
|
||||
/// Customize these to fit your fork:
|
||||
|
||||
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 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 projectOriginAuthor = "lax1dude";
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
public static final boolean enableUpdateService = true;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -19,7 +19,6 @@ package net.lax1dude.eaglercraft.v1_8.mojang.authlib;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
|
@ -94,7 +94,7 @@ public class TexturesProperty {
|
||||
if(meta != null) {
|
||||
String modelStr = meta.optString("model");
|
||||
if(modelStr != null && modelStr.equalsIgnoreCase("slim")) {
|
||||
model = SkinModel.STEVE;
|
||||
model = SkinModel.ALEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ class DisplayList {
|
||||
int attribs = -1;
|
||||
int mode = -1;
|
||||
int count = 0;
|
||||
boolean bindQuad16 = false;
|
||||
boolean bindQuad32 = false;
|
||||
byte bindQuad = 0;
|
||||
|
||||
}
|
@ -40,7 +40,7 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
public class EaglercraftGPU {
|
||||
|
||||
static final GLObjectRecycler<IBufferGL> arrayBufferRecycler = new GLObjectRecycler<IBufferGL>(32) {
|
||||
static final GLObjectRecycler<IBufferGL> arrayBufferRecycler = new GLObjectRecycler<IBufferGL>(256) {
|
||||
|
||||
@Override
|
||||
protected IBufferGL create() {
|
||||
@ -49,7 +49,14 @@ public class EaglercraftGPU {
|
||||
|
||||
@Override
|
||||
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
|
||||
@ -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
|
||||
protected IBufferGL create() {
|
||||
@ -68,7 +75,22 @@ public class EaglercraftGPU {
|
||||
|
||||
@Override
|
||||
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
|
||||
@ -211,8 +233,7 @@ public class EaglercraftGPU {
|
||||
|
||||
if(dp.vertexArray == null) {
|
||||
dp.vertexArray = createGLVertexArray();
|
||||
dp.bindQuad16 = false;
|
||||
dp.bindQuad32 = false;
|
||||
dp.bindQuad = 0;
|
||||
}
|
||||
if(dp.vertexBuffer == null) {
|
||||
dp.vertexBuffer = createGLArrayBuffer();
|
||||
@ -252,8 +273,7 @@ public class EaglercraftGPU {
|
||||
|
||||
if(dp.vertexArray == null) {
|
||||
dp.vertexArray = createGLVertexArray();
|
||||
dp.bindQuad16 = false;
|
||||
dp.bindQuad32 = false;
|
||||
dp.bindQuad = 0;
|
||||
}
|
||||
if(dp.vertexBuffer == null) {
|
||||
dp.vertexBuffer = createGLArrayBuffer();
|
||||
@ -280,21 +300,19 @@ public class EaglercraftGPU {
|
||||
if(dp.mode == GL_QUADS) {
|
||||
int cnt = dp.count;
|
||||
if(cnt > quad16MaxVertices) {
|
||||
if(!dp.bindQuad32) {
|
||||
dp.bindQuad16 = false;
|
||||
dp.bindQuad32 = true;
|
||||
if(dp.bindQuad != 32) {
|
||||
dp.bindQuad = 32;
|
||||
attachQuad32EmulationBuffer(cnt, true);
|
||||
}else {
|
||||
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 {
|
||||
if(!dp.bindQuad16) {
|
||||
dp.bindQuad16 = true;
|
||||
dp.bindQuad32 = false;
|
||||
if(dp.bindQuad != 16) {
|
||||
dp.bindQuad = 16;
|
||||
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 {
|
||||
p.drawArrays(dp.mode, 0, dp.count);
|
||||
@ -560,6 +578,21 @@ public class EaglercraftGPU {
|
||||
_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) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentVertexArray == null) {
|
||||
@ -768,7 +801,7 @@ public class EaglercraftGPU {
|
||||
displayListBuffer.put(buffer);
|
||||
lastRender = null;
|
||||
}else {
|
||||
lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib).update();
|
||||
lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib, mode == GL_QUADS).update();
|
||||
lastRender.drawDirectArrays(mode, 0, count);
|
||||
lastMode = mode;
|
||||
lastCount = count;
|
||||
@ -845,7 +878,7 @@ public class EaglercraftGPU {
|
||||
v3 = v2 + 1;
|
||||
v4 = v3 + 1;
|
||||
buf.put(v1 | (v2 << 16));
|
||||
buf.put(v4 | (v2 << 16));
|
||||
buf.put(v3 | (v1 << 16));
|
||||
buf.put(v3 | (v4 << 16));
|
||||
}
|
||||
buf.flip();
|
||||
@ -862,7 +895,7 @@ public class EaglercraftGPU {
|
||||
v3 = v2 + 1;
|
||||
v4 = v3 + 1;
|
||||
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.flip();
|
||||
@ -891,7 +924,7 @@ public class EaglercraftGPU {
|
||||
}
|
||||
FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update();
|
||||
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;
|
||||
|
@ -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.IShaderGL;
|
||||
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.log4j.LogManager;
|
||||
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.Vector4f;
|
||||
import net.minecraft.util.MathHelper;
|
||||
@ -61,7 +58,7 @@ public class FixedFunctionPipeline {
|
||||
(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;
|
||||
int baseState = attrib | getFragmentState();
|
||||
if(GlStateManager.stateUseExtensionPipeline) {
|
||||
@ -74,13 +71,13 @@ public class FixedFunctionPipeline {
|
||||
self = getPipelineInstanceCore(baseState);
|
||||
}
|
||||
|
||||
StreamBufferInstance sb = self.streamBuffer.getBuffer(buffer.remaining());
|
||||
self.currentVertexArray = sb;
|
||||
EaglercraftGPU.bindGLVertexArray(self.getDirectModeVertexArray());
|
||||
|
||||
EaglercraftGPU.bindGLVertexArray(sb.getVertexArray());
|
||||
EaglercraftGPU.bindGLArrayBuffer(sb.getVertexBuffer());
|
||||
int off = StreamBuffer.uploadData(self.attribStride, buffer.remaining() / self.attribStride, quads);
|
||||
|
||||
_wglBufferSubData(GL_ARRAY_BUFFER, 0, buffer);
|
||||
_wglBufferSubData(GL_ARRAY_BUFFER, off * self.attribStride, buffer);
|
||||
|
||||
self.directBaseOffset = off;
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -132,16 +129,19 @@ public class FixedFunctionPipeline {
|
||||
}
|
||||
|
||||
static FixedFunctionPipeline setupRenderDisplayList(int attribs) {
|
||||
FixedFunctionPipeline self;
|
||||
int baseState = attribs | getFragmentState();
|
||||
if(GlStateManager.stateUseExtensionPipeline) {
|
||||
if(extensionProvider != null) {
|
||||
return getPipelineInstanceExt(baseState, extensionProvider.getCurrentExtensionStateBits(baseState));
|
||||
self = getPipelineInstanceExt(baseState, extensionProvider.getCurrentExtensionStateBits(baseState));
|
||||
}else {
|
||||
throw new IllegalStateException("No extension pipeline is available!");
|
||||
}
|
||||
}else {
|
||||
return getPipelineInstanceCore(baseState);
|
||||
self = getPipelineInstanceCore(baseState);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void drawArrays(int mode, int offset, int count) {
|
||||
@ -151,24 +151,26 @@ public class FixedFunctionPipeline {
|
||||
|
||||
void drawDirectArrays(int mode, int offset, int count) {
|
||||
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
|
||||
offset += directBaseOffset;
|
||||
if(mode == GL_QUADS) {
|
||||
StreamBufferInstance sb = currentVertexArray;
|
||||
if(count > EaglercraftGPU.quad16MaxVertices) {
|
||||
if(!sb.bindQuad32) {
|
||||
sb.bindQuad16 = false;
|
||||
sb.bindQuad32 = true;
|
||||
int offset2 = (offset >> 2) * 6;
|
||||
int count2 = (count >> 2) * 6;
|
||||
if(offset + count > EaglercraftGPU.quad16MaxVertices) {
|
||||
if(directQuads != 32) {
|
||||
directQuads = 32;
|
||||
EaglercraftGPU.attachQuad32EmulationBuffer(count, true);
|
||||
}else {
|
||||
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 {
|
||||
if(!sb.bindQuad16) {
|
||||
sb.bindQuad16 = true;
|
||||
sb.bindQuad32 = false;
|
||||
if(directQuads != 16) {
|
||||
directQuads = 16;
|
||||
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 {
|
||||
EaglercraftGPU.drawArrays(mode, offset, count);
|
||||
@ -180,6 +182,11 @@ public class FixedFunctionPipeline {
|
||||
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;
|
||||
|
||||
public static void loadExtensionPipeline(IExtPipelineCompiler provider) {
|
||||
@ -423,9 +430,9 @@ public class FixedFunctionPipeline {
|
||||
private float stateAlphaTestRef = -999.0f;
|
||||
|
||||
private final IUniformGL stateLightsEnabledUniform1i;
|
||||
private final IUniformGL[] stateLightsVectorsArrayUniform4f = new IUniformGL[4];
|
||||
private final IUniformGL[] stateLightsVectorsArrayUniform4f = new IUniformGL[2];
|
||||
private int stateLightsEnabled = -1;
|
||||
private final Vector4f[] stateLightsVectors = new Vector4f[4];
|
||||
private final Vector4f[] stateLightsVectors = new Vector4f[2];
|
||||
private int stateLightingSerial = -1;
|
||||
|
||||
private final IUniformGL stateLightingAmbientUniform3f;
|
||||
@ -496,8 +503,9 @@ public class FixedFunctionPipeline {
|
||||
private float stateAnisotropicFixH = -999.0f;
|
||||
private float stateAnisotropicFixSerial = 0;
|
||||
|
||||
private final StreamBuffer streamBuffer;
|
||||
private StreamBufferInstance currentVertexArray = null;
|
||||
private IVertexArrayGL directVertexArray;
|
||||
private int directBaseOffset;
|
||||
private byte directQuads;
|
||||
|
||||
private static FloatBuffer matrixCopyBuffer = null;
|
||||
|
||||
@ -572,39 +580,6 @@ public class FixedFunctionPipeline {
|
||||
}
|
||||
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;
|
||||
stateEnableLightmap = (bits & STATE_ENABLE_LIGHTMAP) != 0;
|
||||
@ -899,9 +874,7 @@ public class FixedFunctionPipeline {
|
||||
_wglUniform3f(stateLightingAmbientUniform3f, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(stateEnableMCLighting || DynamicLightsStateManager.isInDynamicLightsPass()) {
|
||||
|
||||
if(!stateHasAttribNormal) {
|
||||
serial = GlStateManager.stateNormalSerial;
|
||||
if(stateNormalSerial != serial) {
|
||||
@ -1089,13 +1062,51 @@ public class FixedFunctionPipeline {
|
||||
}
|
||||
pipelineListTracker.clear();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
PlatformOpenGL._wglDeleteProgram(shaderProgram);
|
||||
streamBuffer.destroy();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -44,7 +44,7 @@ public class FixedFunctionShader {
|
||||
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 PRECISION_INT = "lowp";
|
||||
public static final String PRECISION_INT = "mediump";
|
||||
public static final String PRECISION_FLOAT = "highp";
|
||||
public static final String PRECISION_SAMPLER = "mediump";
|
||||
|
||||
|
@ -76,9 +76,9 @@ public class GlStateManager {
|
||||
static boolean stateMaterial = false;
|
||||
static boolean stateLighting = false;
|
||||
static int stateLightsStackPointer = 0;
|
||||
static final boolean[][] stateLightsEnabled = new boolean[4][8];
|
||||
static final Vector4f[][] stateLightsStack = new Vector4f[4][8];
|
||||
static final int[] stateLightingSerial = new int[4];
|
||||
static final boolean[][] stateLightsEnabled = new boolean[2][8];
|
||||
static final Vector4f[][] stateLightsStack = new Vector4f[2][8];
|
||||
static final int[] stateLightingSerial = new int[2];
|
||||
|
||||
static float stateLightingAmbientR = 0.0f;
|
||||
static float stateLightingAmbientG = 0.0f;
|
||||
|
@ -206,8 +206,7 @@ public class InstancedFontRenderer {
|
||||
EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
|
||||
EaglercraftGPU.vertexAttribDivisor(0, 0);
|
||||
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW);
|
||||
EaglercraftGPU.bindVAOGLArrayBuffer(instancesBuffer);
|
||||
|
||||
EaglercraftGPU.enableVertexAttribArray(1);
|
||||
EaglercraftGPU.vertexAttribPointer(1, 2, GL_SHORT, false, 10, 0);
|
||||
@ -381,7 +380,7 @@ public class InstancedFontRenderer {
|
||||
int l = fontDataBuffer.limit();
|
||||
|
||||
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);
|
||||
|
||||
fontDataBuffer.position(p);
|
||||
@ -395,7 +394,7 @@ public class InstancedFontRenderer {
|
||||
int l = fontBoldDataBuffer.limit();
|
||||
|
||||
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);
|
||||
|
||||
fontBoldDataBuffer.position(p);
|
||||
|
@ -187,8 +187,7 @@ public class InstancedParticleRenderer {
|
||||
EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
|
||||
EaglercraftGPU.vertexAttribDivisor(0, 0);
|
||||
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
|
||||
EaglercraftGPU.bindVAOGLArrayBuffer(instancesBuffer);
|
||||
|
||||
EaglercraftGPU.enableVertexAttribArray(1);
|
||||
EaglercraftGPU.vertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
|
||||
@ -315,7 +314,7 @@ public class InstancedParticleRenderer {
|
||||
int l = particleBuffer.limit();
|
||||
|
||||
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);
|
||||
|
||||
particleBuffer.position(p);
|
||||
|
@ -16,108 +16,53 @@
|
||||
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
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 static final int poolSize = 4;
|
||||
protected static IBufferGL buffer = null;
|
||||
|
||||
protected static final PoolInstance[] pool = new PoolInstance[poolSize];
|
||||
protected static int poolBufferID = 0;
|
||||
protected static int currentOffset = 0;
|
||||
protected static int currentSize = 0;
|
||||
|
||||
static {
|
||||
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;
|
||||
public static IBufferGL getBuffer() {
|
||||
if (buffer == null) {
|
||||
buffer = _wglGenBuffers();
|
||||
instance.vertexBuffer = buffer;
|
||||
return buffer = _wglGenBuffers();
|
||||
}
|
||||
int newSize = instance.vertexBufferSize;
|
||||
if (newSize < requiredMemory) {
|
||||
newSize = (requiredMemory + 0xFFFF) & 0xFFFF0000;
|
||||
instance.vertexBufferSize = newSize;
|
||||
}
|
||||
EaglercraftGPU.bindGLArrayBuffer(buffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, newSize, GL_STREAM_DRAW);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected StreamBufferInstance[] buffers;
|
||||
|
||||
protected final IStreamBufferInitializer initializer;
|
||||
|
||||
public static class StreamBufferInstance {
|
||||
|
||||
protected PoolInstance poolInstance = null;
|
||||
protected IVertexArrayGL vertexArray = null;
|
||||
|
||||
public boolean bindQuad16 = false;
|
||||
public boolean bindQuad32 = false;
|
||||
|
||||
public IVertexArrayGL getVertexArray() {
|
||||
return vertexArray;
|
||||
public static int uploadData(int elSize, int elCount, boolean quads) {
|
||||
EaglercraftGPU.bindGLArrayBuffer(getBuffer());
|
||||
int off = (currentOffset + elSize - 1) / elSize;
|
||||
if (quads) {
|
||||
off = (off + 3) & -4;
|
||||
}
|
||||
|
||||
public IBufferGL getVertexBuffer() {
|
||||
return poolInstance.vertexBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static interface IStreamBufferInitializer {
|
||||
void initialize(IVertexArrayGL vertexArray, IBufferGL vertexBuffer);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
int offBytes = off * elSize;
|
||||
int reqBytes = elCount * elSize;
|
||||
if (currentSize - offBytes >= reqBytes) {
|
||||
currentOffset = offBytes + reqBytes;
|
||||
return off;
|
||||
} else {
|
||||
currentOffset = 0;
|
||||
currentSize = (reqBytes + 0xFFFF) & 0xFFFFF000;
|
||||
_wglBufferData(GL_ARRAY_BUFFER, currentSize, GL_STREAM_DRAW);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void destroyPool() {
|
||||
for(int i = 0; i < pool.length; ++i) {
|
||||
if(pool[i].vertexBuffer != null) {
|
||||
_wglDeleteBuffers(pool[i].vertexBuffer);
|
||||
pool[i].vertexBuffer = null;
|
||||
}
|
||||
if (buffer != null) {
|
||||
_wglDeleteBuffers(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
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();
|
||||
|
||||
|
@ -46,8 +46,8 @@ public class DynamicLightBucketLoader {
|
||||
private int currentLightSourceBucketId = -1;
|
||||
private int lightingBufferSliceLength = -1;
|
||||
|
||||
public static final int MAX_LIGHTS_PER_CHUNK = 12;
|
||||
public static final int LIGHTING_BUFFER_LENGTH = 16 * MAX_LIGHTS_PER_CHUNK + 16;
|
||||
public static final int MAX_LIGHTS_PER_CHUNK = 8;
|
||||
public static final int LIGHTING_BUFFER_LENGTH = 8 * MAX_LIGHTS_PER_CHUNK + 16;
|
||||
|
||||
private final int lightSourceBucketsWidth;
|
||||
private final int lightSourceBucketsHeight;
|
||||
@ -114,26 +114,36 @@ public class DynamicLightBucketLoader {
|
||||
int ser = currentLightSourceBucket.getEaglerSerial();
|
||||
int max = currentLightSourceBucket.size();
|
||||
if(max > 0) {
|
||||
if(max > MAX_LIGHTS_PER_CHUNK) {
|
||||
max = MAX_LIGHTS_PER_CHUNK;
|
||||
}
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int offset = currentLightSourceBucketId * lightingBufferSliceLength;
|
||||
if (lightSourceBucketsSerials[currentLightSourceBucketId] != ser
|
||||
|| lightSourceRenderPosSerials[currentLightSourceBucketId] != currentRenderPosSerial) {
|
||||
lightSourceBucketsSerials[currentLightSourceBucketId] = ser;
|
||||
lightSourceRenderPosSerials[currentLightSourceBucketId] = currentRenderPosSerial;
|
||||
if(max > MAX_LIGHTS_PER_CHUNK) {
|
||||
max = MAX_LIGHTS_PER_CHUNK;
|
||||
}
|
||||
int bucketXOff = -relativeBlockX & -16;
|
||||
int bucketYOff = -relativeBlockY & -16;
|
||||
int bucketZOff = -relativeBlockZ & -16;
|
||||
chunkLightingDataCopyBuffer.clear();
|
||||
chunkLightingDataCopyBuffer.putInt(
|
||||
((bucketXOff & 0xFF) << 8) |
|
||||
((bucketYOff & 0xFF) << 16) |
|
||||
((bucketZOff & 0xFF) << 24)
|
||||
);
|
||||
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) {
|
||||
DynamicLightInstance dl = currentLightSourceBucket.get(i);
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posX - currentRenderX));
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posY - currentRenderY));
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posZ - currentRenderZ));
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.radius);
|
||||
int x = (int)((dl.posX - currentRenderX + bucketXOff) * (1.0f / 0.0009765923f));
|
||||
int y = (int)((dl.posY - currentRenderY + bucketYOff) * (1.0f / 0.0009765923f));
|
||||
int z = (int)((dl.posZ - currentRenderZ + bucketZOff) * (1.0f / 0.0009765923f));
|
||||
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();
|
||||
_wglBufferSubData(_GL_UNIFORM_BUFFER, offset, chunkLightingDataCopyBuffer);
|
||||
|
@ -204,6 +204,8 @@ public class PlatformOpenGL {
|
||||
|
||||
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 _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced);
|
||||
|
@ -1 +1 @@
|
||||
u52
|
||||
u53
|
@ -63,7 +63,7 @@ uniform float u_alphaTestRef1f;
|
||||
|
||||
#ifdef COMPILE_ENABLE_MC_LIGHTING
|
||||
uniform int u_lightsEnabled1i;
|
||||
uniform vec4 u_lightsDirections4fv[4];
|
||||
uniform vec4 u_lightsDirections4fv[2];
|
||||
uniform vec3 u_lightsAmbient3f;
|
||||
#ifndef COMPILE_NORMAL_ATTRIB
|
||||
uniform vec3 u_uniformNormal3f;
|
||||
@ -166,20 +166,14 @@ void main() {
|
||||
#else
|
||||
vec3 normal = u_uniformNormal3f;
|
||||
#endif
|
||||
float diffuse = 0.0;
|
||||
vec4 light;
|
||||
#ifdef EAGLER_HAS_GLES_300
|
||||
for(int i = 0; i < u_lightsEnabled1i; ++i) {
|
||||
#else
|
||||
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) {
|
||||
float diffuse = 0.0;
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
if(i >= u_lightsEnabled1i) {
|
||||
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);
|
||||
#endif
|
||||
|
@ -20,7 +20,6 @@ precision lowp int;
|
||||
precision mediump float;
|
||||
precision mediump sampler2D;
|
||||
|
||||
in vec4 v_position4f;
|
||||
in vec2 v_texCoord2f;
|
||||
in vec4 v_color4f;
|
||||
in vec2 v_lightmap2f;
|
||||
@ -30,16 +29,6 @@ layout(location = 0) out vec4 output4f;
|
||||
uniform sampler2D u_inputTexture;
|
||||
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() {
|
||||
vec4 color = texture(u_inputTexture, v_texCoord2f) * v_color4f;
|
||||
|
||||
@ -47,20 +36,7 @@ void main() {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 dlight;
|
||||
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));
|
||||
color *= texture(u_lightmapTexture, v_lightmap2f);
|
||||
|
||||
output4f = color;
|
||||
}
|
||||
|
@ -28,21 +28,27 @@ layout(location = 3) in vec2 p_lightMap2f;
|
||||
layout(location = 4) in vec2 p_particleSize_texCoordsSize_2i;
|
||||
layout(location = 5) in vec4 p_color4f;
|
||||
|
||||
out vec4 v_position4f;
|
||||
out vec2 v_texCoord2f;
|
||||
out vec4 v_color4f;
|
||||
out vec2 v_lightmap2f;
|
||||
|
||||
uniform mat4 u_modelViewMatrix4f;
|
||||
uniform mat4 u_projectionMatrix4f;
|
||||
uniform mat4 u_inverseViewMatrix4f;
|
||||
uniform vec3 u_texCoordSize2f_particleSize1f;
|
||||
uniform vec3 u_transformParam_1_2_5_f;
|
||||
uniform vec2 u_transformParam_3_4_f;
|
||||
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() {
|
||||
v_color4f = u_color4f * p_color4f.bgra;
|
||||
v_lightmap2f = p_lightMap2f;
|
||||
|
||||
vec2 tex2f = a_position2f * 0.5 + 0.5;
|
||||
tex2f.y = 1.0 - tex2f.y;
|
||||
@ -56,6 +62,40 @@ void main() {
|
||||
pos3f += u_transformParam_1_2_5_f * spos2f.xyy;
|
||||
pos3f.zx += u_transformParam_3_4_f * spos2f;
|
||||
|
||||
v_position4f = u_modelViewMatrix4f * vec4(pos3f, 1.0);
|
||||
gl_Position = u_projectionMatrix4f * v_position4f;
|
||||
vec4 pos4f = u_modelViewMatrix4f * vec4(pos3f, 1.0);
|
||||
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);
|
||||
}
|
||||
|
@ -16,7 +16,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(COMPILE_ENABLE_TEX_GEN) || defined(COMPILE_ENABLE_FOG)
|
||||
in vec4 v_position4f;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_TEXTURE_ATTRIB
|
||||
in vec2 v_texture2f;
|
||||
@ -61,7 +63,7 @@ uniform float u_alphaTestRef1f;
|
||||
|
||||
#ifdef COMPILE_ENABLE_MC_LIGHTING
|
||||
uniform int u_lightsEnabled1i;
|
||||
uniform vec4 u_lightsDirections4fv[4];
|
||||
uniform vec4 u_lightsDirections4fv[2];
|
||||
uniform vec3 u_lightsAmbient3f;
|
||||
#endif
|
||||
|
||||
@ -88,15 +90,9 @@ uniform mat4 u_textureMat4f01;
|
||||
uniform vec2 u_textureAnisotropicFix;
|
||||
#endif
|
||||
|
||||
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];
|
||||
};
|
||||
#ifdef COMPILE_ENABLE_LIGHTMAP
|
||||
in float v_dynamicLight1f;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 output4f;
|
||||
|
||||
@ -151,17 +147,9 @@ void main() {
|
||||
#else
|
||||
float blockLight = u_textureCoords02.x;
|
||||
#endif
|
||||
vec4 dlight;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
blockLight = max(blockLight, v_dynamicLight1f);
|
||||
|
||||
#ifdef COMPILE_LIGHTMAP_ATTRIB
|
||||
color *= texture(u_samplerLightmap, vec2(blockLight, v_lightmap2f.y));
|
||||
#else
|
||||
@ -179,16 +167,18 @@ void main() {
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_ENABLE_MC_LIGHTING
|
||||
#ifdef COMPILE_NORMAL_ATTRIB
|
||||
vec3 normal = v_normal3f;
|
||||
#else
|
||||
vec3 normal = u_uniformNormal3f;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_ENABLE_MC_LIGHTING
|
||||
vec4 light;
|
||||
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];
|
||||
diffuse += max(dot(light.xyz, normal), 0.0) * light.w;
|
||||
}
|
||||
|
@ -18,7 +18,13 @@
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_ENABLE_TEX_GEN
|
||||
out vec3 v_objectPosition3f;
|
||||
@ -46,16 +52,32 @@ out vec2 v_lightmap2f;
|
||||
uniform mat4 u_textureMat4f02;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_ENABLE_LIGHTMAP
|
||||
out float v_dynamicLight1f;
|
||||
#endif
|
||||
|
||||
uniform mat4 u_modelviewMat4f;
|
||||
uniform mat4 u_projectionMat4f;
|
||||
uniform mat4 u_inverseViewMatrix4f;
|
||||
|
||||
#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() {
|
||||
#ifdef COMPILE_ENABLE_TEX_GEN
|
||||
v_objectPosition3f = a_position3f;
|
||||
#endif
|
||||
|
||||
#ifndef _COMPILE_VARYING_POSITION
|
||||
vec4 v_position4f;
|
||||
#endif
|
||||
|
||||
v_position4f = u_modelviewMat4f * vec4(a_position3f, 1.0);
|
||||
|
||||
#ifdef COMPILE_TEXTURE_ATTRIB
|
||||
@ -75,6 +97,42 @@ void main() {
|
||||
vec3 v_lightmapTmp3f = TEX_MAT3(u_textureMat4f02) * vec3(a_lightmap2f, 1.0);
|
||||
v_lightmap2f = v_lightmapTmp3f.xy / v_lightmapTmp3f.z;
|
||||
#endif
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,8 +1,8 @@
|
||||
client-version-integer=52
|
||||
client-version-integer=53
|
||||
client-package-name=net.lax1dude.eaglercraft.v1_8.client
|
||||
client-origin-name=EaglercraftX
|
||||
client-origin-version=u52
|
||||
client-origin-version=u53
|
||||
client-origin-vendor=lax1dude
|
||||
client-fork-name=EaglercraftX
|
||||
client-fork-version=u52
|
||||
client-fork-version=u53
|
||||
client-fork-vendor=lax1dude
|
||||
|
@ -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));
|
||||
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);
|
||||
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+
|
||||
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;
|
||||
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}`),
|
||||
!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)};
|
||||
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]]})),
|
||||
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},
|
||||
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=
|
||||
{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++]=
|
||||
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())}}
|
||||
|
Binary file not shown.
@ -63,6 +63,7 @@ public class PlatformAudio {
|
||||
static AudioBufferSourceNode recDestSilenceNode = null;
|
||||
static GainNode micRecGain = null;
|
||||
static GainNode gameRecGain = null;
|
||||
static HTMLAudioElement silenceElement = null;
|
||||
private static final Map<String, BrowserAudioResource> soundCache = new HashMap<>();
|
||||
private static final List<BrowserAudioHandle> activeSounds = new LinkedList<>();
|
||||
|
||||
@ -253,16 +254,33 @@ public class PlatformAudio {
|
||||
HTMLAudioElement audio = (HTMLAudioElement) PlatformRuntime.doc.createElement("audio");
|
||||
audio.getClassList().add("_eaglercraftX_keepalive_hack");
|
||||
audio.setAttribute("style", "display:none;");
|
||||
audio.setAutoplay(true);
|
||||
audio.setAutoplay(false);
|
||||
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");
|
||||
source.setType("audio/wav");
|
||||
source.setSrc(TeaVMBlobURLManager.registerNewURLByte(silenceFile, "audio/wav").toExternalForm());
|
||||
audio.appendChild(source);
|
||||
audio.addEventListener("seeked", (e) -> {
|
||||
// NOP, wakes up the browser's event loop
|
||||
});
|
||||
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;
|
||||
gameRecGain = null;
|
||||
}
|
||||
if(silenceElement != null) {
|
||||
silenceElement.pause();
|
||||
silenceElement.delete();
|
||||
silenceElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -103,6 +103,7 @@ public class PlatformInput {
|
||||
private static EventListener<?> pointerlock = null;
|
||||
private static EventListener<?> pointerlockerr = null;
|
||||
private static EventListener<?> fullscreen = null;
|
||||
private static EventListener<?> visibilitychange = null;
|
||||
|
||||
private static Map<String,LegacyKeycodeTranslator.LegacyKeycode> keyCodeTranslatorMap = null;
|
||||
|
||||
@ -636,6 +637,12 @@ public class PlatformInput {
|
||||
isWindowFocused = true;
|
||||
}
|
||||
});
|
||||
win.getDocument().addEventListener("visibilitychange", visibilitychange = new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
PlatformAudio.handleVisibilityChange();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
pointerLockSupported = getSupportedPointerLock(win.getDocument());
|
||||
@ -865,7 +872,7 @@ public class PlatformInput {
|
||||
}
|
||||
|
||||
@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;")
|
||||
static native double getDevicePixelRatio(Window win);
|
||||
@ -1513,6 +1520,10 @@ public class PlatformInput {
|
||||
win.removeEventListener("blur", blur);
|
||||
blur = null;
|
||||
}
|
||||
if(visibilitychange != null) {
|
||||
win.getDocument().removeEventListener("visibilitychange", blur);
|
||||
visibilitychange = null;
|
||||
}
|
||||
if(wheel != null) {
|
||||
canvas.removeEventListener("wheel", wheel);
|
||||
wheel = null;
|
||||
|
@ -600,6 +600,11 @@ public class PlatformOpenGL {
|
||||
//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) {
|
||||
switch(instancingImpl) {
|
||||
case INSTANCE_IMPL_CORE:
|
||||
|
@ -72,6 +72,8 @@ public interface WebGL2RenderingContext extends WebGLRenderingContext {
|
||||
|
||||
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);
|
||||
|
||||
void bindBufferRange(int p1, int p2, WebGLBuffer p3, int p4, int p5);
|
||||
|
@ -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 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))
|
||||
|
||||
// Note: Linux kernel uses 4096
|
||||
@ -186,20 +187,28 @@ int main(int argc, char** argv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbgLog("Decompressing classes.wasm.teadbg...");
|
||||
|
||||
result->classesDeobfTEADBGData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfTEADBGData, epwLen);
|
||||
if(!result->classesDeobfTEADBGData) {
|
||||
resultFailed(EPW_INVALID);
|
||||
return -1;
|
||||
if(SLICE_IS_PRESENT(&headerPtr->classesDeobfTEADBGData)) {
|
||||
dbgLog("Decompressing classes.wasm.teadbg...");
|
||||
|
||||
result->classesDeobfTEADBGData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfTEADBGData, epwLen);
|
||||
if(!result->classesDeobfTEADBGData) {
|
||||
resultFailed(EPW_INVALID);
|
||||
return -1;
|
||||
}
|
||||
}else {
|
||||
result->classesDeobfTEADBGData = -1;
|
||||
}
|
||||
|
||||
dbgLog("Decompressing deobfuscator...");
|
||||
|
||||
result->classesDeobfWASMData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfWASMData, epwLen);
|
||||
if(!result->classesDeobfWASMData) {
|
||||
resultFailed(EPW_INVALID);
|
||||
return -1;
|
||||
if(SLICE_IS_PRESENT(&headerPtr->classesDeobfWASMData)) {
|
||||
dbgLog("Decompressing deobfuscator...");
|
||||
|
||||
result->classesDeobfWASMData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfWASMData, epwLen);
|
||||
if(!result->classesDeobfWASMData) {
|
||||
resultFailed(EPW_INVALID);
|
||||
return -1;
|
||||
}
|
||||
}else {
|
||||
result->classesDeobfWASMData = -1;
|
||||
}
|
||||
|
||||
result->numEPKs = numEPKs;
|
||||
|
@ -78,8 +78,8 @@ addToLibrary({
|
||||
|
||||
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 classesDeobfTEADBGURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" }));
|
||||
const classesDeobfWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 3]]], { type: "application/wasm" }));
|
||||
const classesDeobfTEADBGURL = HEAP32[idx + 2] !== -1 ? URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" })) : null;
|
||||
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 crashImg = URL.createObjectURL(new Blob([results[HEAP32[idx + 6]]], { type: results[HEAP32[idx + 7]] }));
|
||||
|
@ -22,6 +22,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.jso.JSBody;
|
||||
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.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.JOrbisAudioBufferDecoder;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter;
|
||||
@ -100,7 +102,10 @@ public class PlatformAudio {
|
||||
if (silenceFile != null) {
|
||||
MemoryStack.push();
|
||||
try {
|
||||
initKeepAliveHack(WASMGCDirectArrayConverter.byteArrayToStackU8Array(silenceFile));
|
||||
int len = silenceFile.length;
|
||||
Address addr = MemoryStack.malloc(len);
|
||||
WASMGCDirectArrayCopy.memcpy(addr, silenceFile, 0, len);
|
||||
initKeepAliveHack(addr, len);
|
||||
}finally {
|
||||
MemoryStack.pop();
|
||||
}
|
||||
@ -112,7 +117,7 @@ public class PlatformAudio {
|
||||
private static native AudioContext getContext();
|
||||
|
||||
@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 {
|
||||
|
||||
|
@ -199,7 +199,7 @@ public class PlatformOpenGL {
|
||||
@Import(module = "platformOpenGL", name = "glReadPixels")
|
||||
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);
|
||||
|
||||
@Import(module = "platformOpenGL", name = "glPolygonOffset")
|
||||
@ -367,7 +367,7 @@ public class PlatformOpenGL {
|
||||
@Import(module = "platformOpenGL", name = "glBufferData")
|
||||
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);
|
||||
|
||||
public static void _wglBufferSubData(int target, int dstOffset, ByteBuffer buffer) {
|
||||
@ -397,7 +397,7 @@ public class PlatformOpenGL {
|
||||
@Import(module = "platformOpenGL", name = "glBufferSubData")
|
||||
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);
|
||||
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
int format, int type, ArrayBufferView typedArray, int offset);
|
||||
|
||||
@ -658,6 +658,9 @@ public class PlatformOpenGL {
|
||||
@Import(module = "platformOpenGL", name = "glDrawElements")
|
||||
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")
|
||||
public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced);
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.jso.JSBody;
|
||||
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.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.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
@ -226,8 +228,10 @@ public class PlatformWebView {
|
||||
}else if(packet.type == SPacketWebViewMessageV4EAG.TYPE_BINARY) {
|
||||
MemoryStack.push();
|
||||
try {
|
||||
sendBinaryMessage(BetterJSStringConverter.stringToJS(currentMessageChannelName),
|
||||
WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.data));
|
||||
int len = packet.data.length;
|
||||
Address addr = MemoryStack.malloc(len);
|
||||
WASMGCDirectArrayCopy.memcpy(addr, packet.data, 0, len);
|
||||
sendBinaryMessage(BetterJSStringConverter.stringToJS(currentMessageChannelName), addr, len);
|
||||
}finally {
|
||||
MemoryStack.pop();
|
||||
}
|
||||
@ -241,7 +245,7 @@ public class PlatformWebView {
|
||||
private static native void sendStringMessage(JSString ch, JSString str);
|
||||
|
||||
@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) {
|
||||
if(channelName.length() > 255) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
@ -124,16 +125,14 @@ public class IndexedDBFilesystem implements IEaglerFilesystem {
|
||||
|
||||
@Override
|
||||
public void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
int len = data.remaining();
|
||||
Uint8Array arr = new Uint8Array(len);
|
||||
arr.set(WASMGCBufferAllocator.getByteBufferView(data));
|
||||
if(!eaglerWrite(database, BetterJSStringConverter.stringToJS(pathName), arr.getBuffer())) {
|
||||
throw new EaglerFileSystemException("Failed to write " + len + " byte file to indexeddb table: " + pathName);
|
||||
if(!eaglerWrite(database, BetterJSStringConverter.stringToJS(pathName),
|
||||
WASMGCBufferAllocator.getByteBufferAddress(data), data.remaining())) {
|
||||
throw new EaglerFileSystemException("Failed to write " + data.remaining() + " byte file to indexeddb table: " + pathName);
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
public boolean eaglerExists(String pathName) {
|
||||
|
@ -21,7 +21,6 @@ import java.util.List;
|
||||
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.jso.core.JSString;
|
||||
import org.teavm.jso.typedarrays.Uint8Array;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
|
@ -21,14 +21,14 @@ import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.Import;
|
||||
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.PlatformRuntime;
|
||||
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.WASMGCClientConfigAdapter;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
@ -71,8 +71,10 @@ public class ClientPlatformSingleplayer {
|
||||
}else {
|
||||
MemoryStack.push();
|
||||
try {
|
||||
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel),
|
||||
WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.contents));
|
||||
int len = packet.contents.length;
|
||||
Address addr = MemoryStack.malloc(len);
|
||||
WASMGCDirectArrayCopy.memcpy(addr, packet.contents, 0, len);
|
||||
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), addr, len);
|
||||
} finally {
|
||||
MemoryStack.pop();
|
||||
}
|
||||
@ -80,7 +82,7 @@ public class ClientPlatformSingleplayer {
|
||||
}
|
||||
|
||||
@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() {
|
||||
if(isSingleThreadMode) {
|
||||
|
@ -22,11 +22,11 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.jso.JSFunctor;
|
||||
import org.teavm.jso.JSObject;
|
||||
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.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.PlatformRuntime;
|
||||
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.wasm_gc_teavm.BetterJSStringConverter;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter;
|
||||
@ -74,8 +74,10 @@ public class ServerPlatformSingleplayer {
|
||||
}else {
|
||||
MemoryStack.push();
|
||||
try {
|
||||
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel),
|
||||
WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.contents));
|
||||
int len = packet.contents.length;
|
||||
Address addr = MemoryStack.malloc(len);
|
||||
WASMGCDirectArrayCopy.memcpy(addr, packet.contents, 0, len);
|
||||
sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), addr, len);
|
||||
} finally {
|
||||
MemoryStack.pop();
|
||||
}
|
||||
@ -83,7 +85,7 @@ public class ServerPlatformSingleplayer {
|
||||
}
|
||||
|
||||
@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() {
|
||||
if(singleThreadMode) {
|
||||
|
@ -100,8 +100,13 @@ function initializeClientPlatfSP(spImports) {
|
||||
});
|
||||
}));
|
||||
|
||||
const classesTEADBGCopy = new Int8Array(classesTEADBG.length);
|
||||
classesTEADBGCopy.set(classesTEADBG, 0);
|
||||
const transferList = [];
|
||||
var classesTEADBGCopy = null;
|
||||
|
||||
if(classesTEADBG) {
|
||||
classesTEADBGCopy = classesTEADBG.buffer.slice(classesTEADBG.byteOffset, classesTEADBG.byteOffset + classesTEADBG.byteLength);
|
||||
transferList.push(classesTEADBGCopy);
|
||||
}
|
||||
|
||||
var eagRuntimeJS;
|
||||
try {
|
||||
@ -116,13 +121,15 @@ function initializeClientPlatfSP(spImports) {
|
||||
return false;
|
||||
}
|
||||
|
||||
transferList.push(eagRuntimeJS);
|
||||
|
||||
workerObj.postMessage({
|
||||
"eaglercraftXOpts": eaglercraftXOpts,
|
||||
"eagruntimeJS": eagRuntimeJS,
|
||||
"classesWASM": classesWASMModule,
|
||||
"classesDeobfWASM": classesDeobfWASMModule,
|
||||
"classesTEADBG": classesTEADBGCopy.buffer
|
||||
});
|
||||
"classesTEADBG": classesTEADBGCopy
|
||||
}, transferList);
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -131,16 +138,16 @@ function initializeClientPlatfSP(spImports) {
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
const copiedArray = new Uint8Array(arr.length);
|
||||
copiedArray.set(arr, 0);
|
||||
const copiedArray = heapArrayBuffer.slice(addr, addr + length);
|
||||
workerObj.postMessage({
|
||||
"ch": channel,
|
||||
"dat": copiedArray.buffer
|
||||
}, [copiedArray.buffer]);
|
||||
"dat": copiedArray
|
||||
}, [copiedArray]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,7 +45,7 @@ async function entryPoint() {
|
||||
|
||||
const teavm = await wasmGC.load(classesWASM, {
|
||||
stackDeobfuscator: {
|
||||
enabled: true,
|
||||
enabled: !!(classesDeobfWASM && classesTEADBGURL),
|
||||
path: classesDeobfWASM,
|
||||
infoLocation: "external",
|
||||
externalInfoPath: classesTEADBGURL
|
||||
|
@ -106,6 +106,8 @@ var keepAliveCallback = null;
|
||||
var showDebugConsole = null;
|
||||
/** @type {function()|null} */
|
||||
var resetSettings = null;
|
||||
/** @type {function()|null} */
|
||||
var handleVisibilityChange = null;
|
||||
|
||||
const runtimeOpts = {
|
||||
localStorageNamespace: "_eaglercraftX",
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
const platfAudioName = "platformAudio";
|
||||
|
||||
/** @type {HTMLAudioElement|null} */
|
||||
var silenceElement = null;
|
||||
|
||||
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) {
|
||||
const copiedData = new Uint8Array(fileData.length);
|
||||
copiedData.set(fileData, 0);
|
||||
audioImports["initKeepAliveHack"] = function(addr, length) {
|
||||
const copiedData = heapArrayBuffer.slice(addr, addr + length);
|
||||
const copiedDataURI = URL.createObjectURL(new Blob([copiedData], {type: "audio/wav"}));
|
||||
const audioElement = /** @type {HTMLAudioElement} */ (document.createElement("audio"));
|
||||
audioElement.classList.add("_eaglercraftX_keepalive_hack");
|
||||
audioElement.setAttribute("style", "display:none;");
|
||||
audioElement.autoplay = true;
|
||||
audioElement.autoplay = false;
|
||||
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"));
|
||||
sourceElement.type = "audio/wav";
|
||||
sourceElement.src = copiedDataURI;
|
||||
audioElement.appendChild(sourceElement);
|
||||
audioElement.addEventListener("seeked", function() {
|
||||
// NOP, wakes up the browser's event loop
|
||||
});
|
||||
parentElement.appendChild(audioElement);
|
||||
silenceElement = audioElement;
|
||||
};
|
||||
|
||||
handleVisibilityChange = function() {
|
||||
if (silenceElement) {
|
||||
if (document.visibilityState === "hidden") {
|
||||
silenceElement.play();
|
||||
} else {
|
||||
silenceElement.pause();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -144,13 +144,24 @@ function eaglerReadImpl(database, pathName) {
|
||||
|
||||
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 {string} pathName
|
||||
* @param {ArrayBuffer} arr
|
||||
* @return {Promise}
|
||||
*/
|
||||
function eaglerWriteImpl(database, pathName, arr) {
|
||||
function eaglerWriteImpl0(database, pathName, arr) {
|
||||
return new Promise(function(resolve) {
|
||||
const tx = database.transaction("filesystem", "readwrite");
|
||||
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) {
|
||||
const oldData = await eaglerReadImpl(database, pathNameOld);
|
||||
if(!oldData || !(await eaglerWriteImpl(database, pathNameNew, oldData))) {
|
||||
if(!oldData || !(await eaglerWriteImpl0(database, pathNameNew, oldData))) {
|
||||
return false;
|
||||
}
|
||||
return await eaglerDeleteImpl(database, pathNameOld);
|
||||
@ -209,7 +220,7 @@ eagruntimeImpl.platformFilesystem["eaglerMove"] = new WebAssembly.Suspending(eag
|
||||
*/
|
||||
async function eaglerCopyImpl(database, pathNameOld, pathNameNew) {
|
||||
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);
|
||||
|
@ -118,7 +118,8 @@ async function initPlatformInput(inputImports) {
|
||||
blur: null,
|
||||
pointerlock: null,
|
||||
pointerlockerr: null,
|
||||
fullscreenChange: null
|
||||
fullscreenChange: null,
|
||||
visibilitychange: null
|
||||
};
|
||||
|
||||
touchKeyboardOpenZone = document.createElement("div");
|
||||
@ -351,6 +352,11 @@ async function initPlatformInput(inputImports) {
|
||||
pushEvent(EVENT_TYPE_INPUT, EVENT_INPUT_FOCUS, null);
|
||||
});
|
||||
|
||||
document.addEventListener("visibilitychange", currentEventListeners.visibilitychange = function(/** Event */ evt) {
|
||||
if (handleVisibilityChange)
|
||||
handleVisibilityChange();
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} evtType
|
||||
* @param {KeyboardEvent} evt
|
||||
@ -1138,6 +1144,10 @@ async function initPlatformInput(inputImports) {
|
||||
window.removeEventListener("blur", /** @type {function(Event)} */ (currentEventListeners.blur));
|
||||
currentEventListeners.blur = null;
|
||||
}
|
||||
if(currentEventListeners.visibilitychange) {
|
||||
document.removeEventListener("visibilitychange", currentEventListeners.visibilitychange);
|
||||
currentEventListeners.visibilitychange = null;
|
||||
}
|
||||
if(currentEventListeners.pointerlock) {
|
||||
document.removeEventListener("pointerlockchange", /** @type {function(Event)} */ (currentEventListeners.pointerlock));
|
||||
currentEventListeners.pointerlock = null;
|
||||
|
@ -99,7 +99,7 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) {
|
||||
glImports["glColorMask"] = ctx.colorMask.bind(ctx);
|
||||
glImports["glDrawBuffers"] = glesVersIn >= 300 ? ctx.drawBuffers.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDrawBuffers");
|
||||
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["glLineWidth"] = ctx.lineWidth.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["glDeleteQueries"] = glesVersIn >= 300 ? ctx.deleteQuery.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDeleteQueries");
|
||||
glImports["glBindBuffer"] = ctx.bindBuffer.bind(ctx);
|
||||
glImports["glBufferData"] = glImports["glBufferData0"] = ctx.bufferData.bind(ctx);
|
||||
glImports["glBufferSubData"] = glImports["glBufferSubData0"] = ctx.bufferSubData.bind(ctx);
|
||||
glImports["glBufferData"] = ctx.bufferData.bind(ctx);
|
||||
glImports["glBufferSubData"] = ctx.bufferSubData.bind(ctx);
|
||||
glImports["glEnableVertexAttribArray"] = ctx.enableVertexAttribArray.bind(ctx);
|
||||
glImports["glDisableVertexAttribArray"] = ctx.disableVertexAttribArray.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["glTexParameterf"] = ctx.texParameterf.bind(ctx);
|
||||
glImports["glTexParameteri"] = ctx.texParameteri.bind(ctx);
|
||||
glImports["glTexImage3D"] = glImports["glTexImage3D0"] = glesVersIn >= 300 ? ctx.texImage3D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexImage3D");
|
||||
glImports["glTexImage2D"] = glImports["glTexImage2D0"] = ctx.texImage2D.bind(ctx);
|
||||
glImports["glTexSubImage2D"] = glImports["glTexSubImage2D0"] = ctx.texSubImage2D.bind(ctx);
|
||||
glImports["glTexImage3D"] = glesVersIn >= 300 ? ctx.texImage3D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexImage3D");
|
||||
glImports["glTexImage2D"] = ctx.texImage2D.bind(ctx);
|
||||
glImports["glTexSubImage2D"] = ctx.texSubImage2D.bind(ctx);
|
||||
glImports["glCopyTexSubImage2D"] = ctx.copyTexSubImage2D.bind(ctx);
|
||||
glImports["glTexStorage2D"] = glesVersIn >= 300 ? ctx.texStorage2D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexStorage2D");
|
||||
glImports["glPixelStorei"] = ctx.pixelStorei.bind(ctx);
|
||||
@ -145,6 +145,7 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) {
|
||||
glImports["glGetProgramInfoLog"] = ctx.getProgramInfoLog.bind(ctx);
|
||||
glImports["glDrawArrays"] = ctx.drawArrays.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["glGetAttribLocation"] = ctx.getAttribLocation.bind(ctx);
|
||||
glImports["glGetUniformLocation"] = ctx.getUniformLocation.bind(ctx);
|
||||
@ -299,7 +300,6 @@ function setNoGLContext(glImports) {
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawBuffers");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glReadBuffer");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels0");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glPolygonOffset");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glLineWidth");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glGenBuffers");
|
||||
@ -318,9 +318,7 @@ function setNoGLContext(glImports) {
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glDeleteQueries");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glBindBuffer");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData0");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData0");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glEnableVertexAttribArray");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glDisableVertexAttribArray");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glVertexAttribPointer");
|
||||
@ -329,11 +327,8 @@ function setNoGLContext(glImports) {
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameterf");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameteri");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D0");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D0");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D0");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glCopyTexSubImage2D");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glTexStorage2D");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glPixelStorei");
|
||||
@ -350,6 +345,7 @@ function setNoGLContext(glImports) {
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glGetProgramInfoLog");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawArrays");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawElements");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glDrawRangeElements");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glBindAttribLocation");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glGetAttribLocation");
|
||||
setUnsupportedFunc(glImports, platfOpenGLName, "glGetUniformLocation");
|
||||
|
@ -121,19 +121,18 @@ function initializePlatfWebView(webViewImports) {
|
||||
|
||||
/**
|
||||
* @param {string} ch
|
||||
* @param {Uint8Array} bin
|
||||
* @param {number} addr
|
||||
* @param {number} length
|
||||
*/
|
||||
webViewImports["sendBinaryMessage"] = function(ch, bin) {
|
||||
webViewImports["sendBinaryMessage"] = function(ch, addr, length) {
|
||||
try {
|
||||
var w;
|
||||
if(currentIFrame != null && (w = currentIFrame.contentWindow) != null) {
|
||||
const copiedArray = new Uint8Array(bin.length);
|
||||
copiedArray.set(bin, 0);
|
||||
w.postMessage({
|
||||
"ver": 1,
|
||||
"channel": ch,
|
||||
"type": "binary",
|
||||
"data": copiedArray.buffer
|
||||
"data": heapArrayBuffer.slice(addr, addr + length)
|
||||
}, "*");
|
||||
}else {
|
||||
eagError("Server tried to send the WebView a message, but the message channel is not open!");
|
||||
|
@ -57,15 +57,15 @@ function initializeServerPlatfSP(spImports) {
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {Uint8Array} arr
|
||||
* @param {number} addr
|
||||
* @param {number} length
|
||||
*/
|
||||
spImports["sendPacket"] = function(channel, arr) {
|
||||
const copiedArray = new Uint8Array(arr.length);
|
||||
copiedArray.set(arr, 0);
|
||||
spImports["sendPacket"] = function(channel, addr, length) {
|
||||
const copiedArray = heapArrayBuffer.slice(addr, addr + length);
|
||||
postMessage({
|
||||
"ch": channel,
|
||||
"dat": copiedArray.buffer
|
||||
}, [copiedArray.buffer]);
|
||||
"dat": copiedArray
|
||||
}, [copiedArray]);
|
||||
};
|
||||
|
||||
spImports["getAvailablePackets"] = serverMessageQueue.getLength.bind(serverMessageQueue);
|
||||
|
Reference in New Issue
Block a user