This commit is contained in:
eaglercraft 2024-12-14 21:28:53 -08:00
parent f4fab59961
commit a04cff9aea
37 changed files with 568 additions and 205 deletions

View File

@ -592,7 +592,7 @@ eaglercraft.singleplayer.demo.create.create.tooltip=Play the Minecraft 1.8 demo
eaglercraft.singleplayer.demo.create.join=Join Shared World
eaglercraft.singleplayer.demo.create.join.tooltip=Join someone else's world and play multiplayer
eaglercraft.createWorld.seedNote=Note: Vanilla seeds now work!
eaglercraft.createWorld.seedNote=Note: Vanilla seeds work
eaglercraft.singleplayer.oldseedwarning.title=Old World Detected!
eaglercraft.singleplayer.oldseedwarning.msg1=Please use EaglercraftX u32 or older to "Re-Create" this world

View File

@ -100,9 +100,8 @@ public class GuiMultiplayer extends GuiScreen implements GuiYesNoCallback {
this.serverListSelector.func_148195_a(this.savedServerList);
if (lanServerList == null) {
lanServerList = new LANServerList();
} else {
lanServerList.forceRefresh();
}
lanServerList.forceRefresh();
} else {
this.serverListSelector.setDimensions(this.width, this.height, 32, this.height - 64);
}

View File

@ -14,8 +14,6 @@ import org.lwjgl.glfw.GLFWGamepadState;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.system.MemoryStack;
import net.lax1dude.eaglercraft.v1_8.Display;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
@ -302,7 +300,7 @@ public class PlatformInput {
update(0);
}
private static final long[] syncTimer = new long[1];
private static long syncTimer = 0l;
public static void update(int limitFps) {
glfwPollEvents();
@ -311,10 +309,23 @@ public class PlatformInput {
glfwVSyncState = vsync;
}
glfwSwapBuffers(win);
if(limitFps > 0 && !vsync) {
Display.sync(limitFps, syncTimer);
if(!vsync && limitFps > 0 && limitFps <= 1000) {
long frameNanos = (1000000000l / limitFps);
if(syncTimer == 0l) {
syncTimer = System.nanoTime() + frameNanos;
}else {
syncTimer[0] = 0l;
long nanos = System.nanoTime();
int remaining = (int)((syncTimer - nanos) / 1000000l);
if(remaining > 0) {
PlatformRuntime.sleep(remaining);
nanos = System.nanoTime();
}
if((syncTimer += frameNanos) < nanos) {
syncTimer = nanos;
}
}
}else {
syncTimer = 0l;
}
}

View File

@ -647,4 +647,8 @@ public class PlatformRuntime {
// nope
}
public static boolean immediateContinueSupported() {
return false;
}
}

View File

@ -33,48 +33,74 @@ public class EaglerLWJGLAllocator {
return allocCount;
}
private static final ByteBuffer ZERO_LENGTH_BYTE_BUFFER = new EaglerLWJGLByteBuffer(0l, 0, true);
public static ByteBuffer allocByteBuffer(int len) {
if(len != 0) {
long ret = JEmalloc.nje_malloc(len);
if(ret == 0l) {
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
}
if(enableAllocCount) ++allocCount;
return new EaglerLWJGLByteBuffer(ret, len, true);
}else {
return ZERO_LENGTH_BYTE_BUFFER;
}
}
private static final ShortBuffer ZERO_LENGTH_SHORT_BUFFER = new EaglerLWJGLShortBuffer(0l, 0, true);
public static ShortBuffer allocShortBuffer(int len) {
if(len != 0) {
long ret = JEmalloc.nje_malloc(len << 1);
if(ret == 0l) {
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
}
if(enableAllocCount) ++allocCount;
return new EaglerLWJGLShortBuffer(ret, len, true);
}else {
return ZERO_LENGTH_SHORT_BUFFER;
}
}
private static final IntBuffer ZERO_LENGTH_INT_BUFFER = new EaglerLWJGLIntBuffer(0l, 0, true);
public static IntBuffer allocIntBuffer(int len) {
if(len != 0) {
long ret = JEmalloc.nje_malloc(len << 2);
if(ret == 0l) {
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
}
if(enableAllocCount) ++allocCount;
return new EaglerLWJGLIntBuffer(ret, len, true);
}else {
return ZERO_LENGTH_INT_BUFFER;
}
}
private static final FloatBuffer ZERO_LENGTH_FLOAT_BUFFER = new EaglerLWJGLFloatBuffer(0l, 0, true);
public static FloatBuffer allocFloatBuffer(int len) {
if(len != 0) {
long ret = JEmalloc.nje_malloc(len << 2);
if(ret == 0l) {
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
}
if(enableAllocCount) ++allocCount;
return new EaglerLWJGLFloatBuffer(ret, len, true);
}else {
return ZERO_LENGTH_FLOAT_BUFFER;
}
}
public static void freeByteBuffer(ByteBuffer buffer) {
if(buffer instanceof EaglerLWJGLByteBuffer) {
EaglerLWJGLByteBuffer buf = (EaglerLWJGLByteBuffer)buffer;
if(buf.original) {
if(buf.address != 0l) {
JEmalloc.nje_free(buf.address);
if(enableAllocCount) --allocCount;
}
}else {
throwNotOriginal(buffer);
}
@ -96,8 +122,10 @@ public class EaglerLWJGLAllocator {
if(buffer instanceof EaglerLWJGLShortBuffer) {
EaglerLWJGLShortBuffer buf = (EaglerLWJGLShortBuffer)buffer;
if(buf.original) {
if(buf.address != 0l) {
JEmalloc.nje_free(buf.address);
if(enableAllocCount) --allocCount;
}
}else {
throwNotOriginal(buffer);
}
@ -119,8 +147,10 @@ public class EaglerLWJGLAllocator {
if(buffer instanceof EaglerLWJGLIntBuffer) {
EaglerLWJGLIntBuffer buf = (EaglerLWJGLIntBuffer)buffer;
if(buf.original) {
if(buf.address != 0l) {
JEmalloc.nje_free(buf.address);
if(enableAllocCount) --allocCount;
}
}else {
throwNotOriginal(buffer);
}
@ -142,8 +172,10 @@ public class EaglerLWJGLAllocator {
if(buffer instanceof EaglerLWJGLFloatBuffer) {
EaglerLWJGLFloatBuffer buf = (EaglerLWJGLFloatBuffer)buffer;
if(buf.original) {
if(buf.address != 0l) {
JEmalloc.nje_free(buf.address);
if(enableAllocCount) --allocCount;
}
}else {
throwNotOriginal(buffer);
}

View File

@ -19,7 +19,6 @@ import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
*/
public class Display {
private static long lastSwap = 0l;
private static long lastDPIUpdate = -250l;
private static float cacheDPI = 1.0f;
@ -79,41 +78,6 @@ public class Display {
PlatformInput.update(limitFramerate);
}
private static final long[] defaultSyncPtr = new long[1];
public static void sync(int limitFramerate) {
sync(limitFramerate, defaultSyncPtr);
}
public static boolean sync(int limitFramerate, long[] timerPtr) {
boolean limitFPS = limitFramerate > 0 && limitFramerate < 1000;
boolean blocked = false;
if(limitFPS) {
if(timerPtr[0] == 0l) {
timerPtr[0] = EagRuntime.steadyTimeMillis();
}else {
long millis = EagRuntime.steadyTimeMillis();
long frameMillis = (1000l / limitFramerate);
long frameTime = millis - timerPtr[0];
if(frameTime > 2000l || frameTime < 0l) {
frameTime = frameMillis;
timerPtr[0] = millis;
}else {
timerPtr[0] += frameMillis;
}
if(frameTime >= 0l && frameTime < frameMillis) {
EagUtils.sleep(frameMillis - frameTime);
blocked = true;
}
}
}else {
timerPtr[0] = 0l;
}
return blocked;
}
public static boolean contextLost() {
return PlatformInput.contextLost();
}

View File

@ -375,4 +375,8 @@ public class EagRuntime {
PlatformRuntime.immediateContinue();
}
public static boolean immediateContinueSupported() {
return PlatformRuntime.immediateContinueSupported();
}
}

View File

@ -142,6 +142,16 @@ public class EaglerInputStream extends InputStream {
}
}
public static byte[] inputStreamToBytesNoClose(InputStream is) throws IOException {
EaglerOutputStream os = new EaglerOutputStream(1024);
byte[] buf = new byte[1024];
int i;
while ((i = is.read(buf)) != -1) {
os.write(buf, 0, i);
}
return os.toByteArray();
}
public byte[] getAsArray() {
if (pos == 0 && count == buf.length) {
return buf;

View File

@ -10,7 +10,7 @@ public class EaglercraftVersion {
/// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u44";
public static final String projectForkVersion = "u45";
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 = "u44";
public static final String projectOriginVersion = "u45";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
// EPK Version Identifier
public static final String EPKVersionIdentifier = "u44"; // Set to null to disable EPK version check
public static final String EPKVersionIdentifier = "u45"; // 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 = 44;
public static final int updateBundlePackageVersionInt = 45;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;

View File

@ -211,7 +211,7 @@ public class EaglerFolderResourcePack extends AbstractResourcePack {
i += j;
}
}else {
buffer = EaglerInputStream.inputStreamToBytes(ziss);
buffer = EaglerInputStream.inputStreamToBytesNoClose(ziss);
}
(new VFile2(prefix, folderName, fn.substring(prefixLen))).setAllBytes(buffer);
totalSize += buffer.length;

View File

@ -930,6 +930,8 @@ public class EaglercraftGPU {
InstancedParticleRenderer.destroy();
EffectPipelineFXAA.destroy();
TextureCopyUtil.destroy();
FixedFunctionPipeline.flushCache();
StreamBuffer.destroyPool();
emulatedVAOs = false;
emulatedVAOState = null;
glesVers = -1;

View File

@ -76,8 +76,8 @@ public class FixedFunctionPipeline {
StreamBufferInstance sb = self.streamBuffer.getBuffer(buffer.remaining());
self.currentVertexArray = sb;
EaglercraftGPU.bindGLBufferArray(sb.vertexArray);
EaglercraftGPU.bindGLArrayBuffer(sb.vertexBuffer);
EaglercraftGPU.bindGLBufferArray(sb.getVertexArray());
EaglercraftGPU.bindGLArrayBuffer(sb.getVertexBuffer());
_wglBufferSubData(GL_ARRAY_BUFFER, 0, buffer);

View File

@ -7,7 +7,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/**
* Copyright (c) 2023 lax1dude. All Rights Reserved.
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -23,10 +23,48 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
*/
public class StreamBuffer {
public static final int poolSize = 16;
public final int initialSize;
public final int initialCount;
public final int maxCount;
protected static final PoolInstance[] pool = new PoolInstance[poolSize];
protected static int poolBufferID = 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 PoolInstance fillPoolInstance() {
PoolInstance ret = pool[poolBufferID++];
if(poolBufferID > poolSize - 1) {
poolBufferID = 0;
}
return ret;
}
private static void resizeInstance(PoolInstance instance, int requiredMemory) {
if(instance.vertexBuffer == null) {
instance.vertexBuffer = _wglGenBuffers();
}
if(instance.vertexBufferSize < requiredMemory) {
int newSize = (requiredMemory & 0xFFFFF000) + 0x2000;
EaglercraftGPU.bindGLArrayBuffer(instance.vertexBuffer);
_wglBufferData(GL_ARRAY_BUFFER, newSize, GL_STREAM_DRAW);
instance.vertexBufferSize = newSize;
}
}
protected StreamBufferInstance[] buffers;
protected int currentBufferId = 0;
@ -36,9 +74,8 @@ public class StreamBuffer {
public static class StreamBufferInstance {
protected PoolInstance poolInstance = null;
protected IBufferArrayGL vertexArray = null;
protected IBufferGL vertexBuffer = null;
protected int vertexBufferSize = 0;
public boolean bindQuad16 = false;
public boolean bindQuad32 = false;
@ -48,7 +85,7 @@ public class StreamBuffer {
}
public IBufferGL getVertexBuffer() {
return vertexBuffer;
return poolInstance.vertexBuffer;
}
}
@ -58,9 +95,14 @@ public class StreamBuffer {
}
public StreamBuffer(int initialSize, int initialCount, int maxCount, IStreamBufferInitializer initializer) {
if(maxCount > poolSize) {
maxCount = poolSize;
}
this.buffers = new StreamBufferInstance[initialCount];
for(int i = 0; i < this.buffers.length; ++i) {
this.buffers[i] = new StreamBufferInstance();
StreamBufferInstance j = new StreamBufferInstance();
j.poolInstance = fillPoolInstance();
this.buffers[i] = j;
}
this.initialSize = initialSize;
this.initialCount = initialCount;
@ -70,18 +112,10 @@ public class StreamBuffer {
public StreamBufferInstance getBuffer(int requiredMemory) {
StreamBufferInstance next = buffers[(currentBufferId++) % buffers.length];
if(next.vertexBuffer == null) {
next.vertexBuffer = _wglGenBuffers();
}
resizeInstance(next.poolInstance, requiredMemory);
if(next.vertexArray == null) {
next.vertexArray = EaglercraftGPU.createGLBufferArray();
initializer.initialize(next.vertexArray, next.vertexBuffer);
}
if(next.vertexBufferSize < requiredMemory) {
int newSize = (requiredMemory & 0xFFFFF000) + 0x2000;
EaglercraftGPU.bindGLArrayBuffer(next.vertexBuffer);
_wglBufferData(GL_ARRAY_BUFFER, newSize, GL_STREAM_DRAW);
next.vertexBufferSize = newSize;
initializer.initialize(next.vertexArray, next.poolInstance.vertexBuffer);
}
return next;
}
@ -102,12 +136,10 @@ public class StreamBuffer {
if(buffers[i].vertexArray != null) {
EaglercraftGPU.destroyGLBufferArray(buffers[i].vertexArray);
}
if(buffers[i].vertexBuffer != null) {
_wglDeleteBuffers(buffers[i].vertexBuffer);
}
}
}
buffers = newArray;
refill();
}
overflowCounter = 0;
}else if(overflowCounter > 15) {
@ -125,25 +157,51 @@ public class StreamBuffer {
}
}
buffers = newArray;
refill();
}
overflowCounter = 0;
}
currentBufferId = 0;
}
private void refill() {
for(int i = 0; i < buffers.length; ++i) {
PoolInstance j = fillPoolInstance();
StreamBufferInstance k = buffers[i];
if(j != k.poolInstance) {
PoolInstance l = k.poolInstance;
k.poolInstance = j;
if(k.vertexArray != null) {
if(j.vertexBuffer == null) {
resizeInstance(j, l.vertexBufferSize);
}
initializer.initialize(k.vertexArray, j.vertexBuffer);
}
}
}
}
public void destroy() {
for(int i = 0; i < buffers.length; ++i) {
StreamBufferInstance next = buffers[i];
if(next.vertexArray != null) {
EaglercraftGPU.destroyGLBufferArray(next.vertexArray);
}
if(next.vertexBuffer != null) {
_wglDeleteBuffers(next.vertexBuffer);
}
}
buffers = new StreamBufferInstance[initialCount];
for(int i = 0; i < buffers.length; ++i) {
buffers[i] = new StreamBufferInstance();
for(int i = 0; i < initialCount; ++i) {
StreamBufferInstance j = new StreamBufferInstance();
j.poolInstance = fillPoolInstance();
buffers[i] = j;
}
}
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;
}
}
}

View File

@ -153,7 +153,7 @@ public class SingleplayerServerController implements ISaveFormat {
}
public static boolean isChannelNameAllowed(String ch) {
return !IPC_CHANNEL.equals(ch) && !PLAYER_CHANNEL.equals(ch);
return !ch.startsWith("~!");
}
public static void openPlayerChannel(String ch) {

View File

@ -1,5 +1,6 @@
package net.lax1dude.eaglercraft.v1_8.sp.lan;
import java.util.LinkedList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
@ -42,6 +43,8 @@ class LANClientPeer {
protected long startTime;
protected String localICECandidate = null;
protected boolean localChannel = false;
protected List<byte[]> packetPreBuffer = null;
protected LANClientPeer(String clientId) {
this.clientId = clientId;
@ -75,7 +78,19 @@ class LANClientPeer {
protected void handleSuccess() {
if(state == SENT_ICE_CANDIDATE) {
if(localChannel) {
SingleplayerServerController.openPlayerChannel(clientId);
PlatformWebRTC.serverLANPeerMapIPC(clientId, clientId);
if(packetPreBuffer != null) {
for(byte[] b : packetPreBuffer) {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData(clientId, b));
}
packetPreBuffer = null;
}
state = CONNECTED;
}else {
state = RECEIVED_SUCCESS;
}
}else if(state != CONNECTED) {
logger.error("Relay [{}] unexpected IPacket05ClientSuccess for '{}'", LANServerController.lanRelaySocket.getURI(), clientId);
}
@ -113,13 +128,7 @@ class LANClientPeer {
localICECandidate = ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates;
continue read_loop;
}
}
case RECEIVED_ICE_CANDIDATE: {
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
LANServerController.lanRelaySocket.writePacket(new RelayPacket03ICECandidate(clientId, ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates));
state = SENT_ICE_CANDIDATE;
continue read_loop;
}
break;
}
case RECEIVED_DESCRIPTION: {
if(evt instanceof LANPeerEvent.LANPeerDescriptionEvent) {
@ -127,15 +136,50 @@ class LANClientPeer {
state = SENT_DESCRIPTION;
continue read_loop;
}
break;
}
case RECEIVED_ICE_CANDIDATE: {
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
LANServerController.lanRelaySocket.writePacket(new RelayPacket03ICECandidate(clientId, ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates));
state = SENT_ICE_CANDIDATE;
continue read_loop;
}else if(evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
localChannel = true;
continue read_loop;
}else if(evt instanceof LANPeerEvent.LANPeerPacketEvent) {
if(packetPreBuffer == null) packetPreBuffer = new LinkedList<>();
packetPreBuffer.add(((LANPeerEvent.LANPeerPacketEvent)evt).payload);
continue read_loop;
}
break;
}
case SENT_ICE_CANDIDATE: {
if(evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
localChannel = true;
continue read_loop;
}else if(evt instanceof LANPeerEvent.LANPeerPacketEvent) {
if(packetPreBuffer == null) packetPreBuffer = new LinkedList<>();
packetPreBuffer.add(((LANPeerEvent.LANPeerPacketEvent)evt).payload);
continue read_loop;
}
break;
}
case SENT_ICE_CANDIDATE:
case RECEIVED_SUCCESS: {
if(evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
SingleplayerServerController.openPlayerChannel(clientId);
PlatformWebRTC.serverLANPeerMapIPC(clientId, clientId);
if(packetPreBuffer != null) {
for(byte[] b : packetPreBuffer) {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData(clientId, b));
}
packetPreBuffer = null;
}
state = CONNECTED;
continue read_loop;
}else if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
continue read_loop;
}
break;
}
case CONNECTED: {
if(evt instanceof LANPeerEvent.LANPeerPacketEvent) {
@ -144,6 +188,7 @@ class LANClientPeer {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData(clientId, ((LANPeerEvent.LANPeerPacketEvent)evt).payload));
continue read_loop;
}
break;
}
default: {
break;

View File

@ -12,6 +12,7 @@ import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformWebRTC;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.sp.SingleplayerServerController;
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayManager;
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayServerSocket;
import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.*;
@ -142,7 +143,9 @@ public class LANServerController {
while((pkt = lanRelaySocket.readPacket()) != null) {
if(pkt instanceof RelayPacket02NewClient) {
RelayPacket02NewClient ipkt = (RelayPacket02NewClient) pkt;
if(clients.containsKey(ipkt.clientId)) {
if(!SingleplayerServerController.isChannelNameAllowed(ipkt.clientId)) {
logger.error("Relay [{}] relay tried to open disallowed channel name: '{}'", lanRelaySocket.getURI(), ipkt.clientId);
}else if(clients.containsKey(ipkt.clientId)) {
logger.error("Relay [{}] relay provided duplicate client '{}'", lanRelaySocket.getURI(), ipkt.clientId);
}else {
clients.put(ipkt.clientId, new LANClientPeer(ipkt.clientId));

View File

@ -103,11 +103,10 @@ public class WorldConverterEPK {
public static byte[] exportWorld(String worldName) {
String realWorldName = worldName;
String worldOwner = "UNKNOWN";
String splitter = new String(new char[] { (char)253, (char)233, (char)233 });
if(worldName.contains(splitter)) {
int i = worldName.lastIndexOf(splitter);
worldOwner = worldName.substring(i + 3);
realWorldName = worldName.substring(0, i);
int j = worldName.lastIndexOf(new String(new char[] { (char)253, (char)233, (char)233 }));
if(j != -1) {
worldOwner = worldName.substring(j + 3);
realWorldName = worldName.substring(0, j);
}
VFile2 worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(realWorldName, false).getWorldDirectory();
logger.info("Exporting world directory \"{}\" as EPK", worldDir.getPath());

View File

@ -70,7 +70,6 @@ public class WorldConverterMCA {
ZipEntry f = null;
int lastProgUpdate = 0;
int prog = 0;
byte[] bb = new byte[16384];
while ((f = zis.getNextEntry()) != null) {
if (f.getName().contains("__MACOSX/")) continue;
if (f.isDirectory()) continue;
@ -85,7 +84,7 @@ public class WorldConverterMCA {
j += k;
}
}else {
b = EaglerInputStream.inputStreamToBytes(zis);
b = EaglerInputStream.inputStreamToBytesNoClose(zis);
}
String fileName = f.getName().substring(folderPrefixOffset);
if (fileName.equals("level.dat") || fileName.equals("level.dat_old")) {

View File

@ -382,7 +382,7 @@ public class ClientBootFactory {
System.arraycopy(classesServerJS, 0, concatClassesServerJS, appendToClassesServerJS.length, classesServerJS.length);
TeaVMBlobURLHandle classesServerJSURL = TeaVMBlobURLManager.registerNewURLByte(concatClassesServerJS, "text/javascript");
toCleanOnException.add(classesServerJSURL);
launchOpts.put("serverWorkerURI", classesServerJSURL);
launchOpts.put("serverWorkerURI", classesServerJSURL.toExternalForm());
doUpdateMessage(cb, "Resolving assets.epk (" + clientData.epkFiles.get(0).dataUUID + ")");
TeaVMBlobURLHandle assetsEPKURL = loadingCache.get(new UUIDStringPair(clientData.epkFiles.get(0).dataUUID, "application/octet-stream"));
if(assetsEPKURL == null) {

View File

@ -36,8 +36,6 @@ import org.teavm.jso.gamepad.Gamepad;
import org.teavm.jso.gamepad.GamepadButton;
import org.teavm.jso.gamepad.GamepadEvent;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ClientMain;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.EarlyLoadScreen;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.InputEvent;
@ -889,7 +887,7 @@ public class PlatformInput {
update(0);
}
private static final long[] syncTimer = new long[1];
private static double syncTimer = 0.0;
public static void update(int fpsLimit) {
double r = getDevicePixelRatio(win);
@ -943,21 +941,44 @@ public class PlatformInput {
PlatformScreenRecord.captureFrameHook();
if(getVisibilityState(win.getDocument())) {
if(vsyncSupport && vsync) {
syncTimer[0] = 0l;
syncTimer = 0.0;
asyncRequestAnimationFrame();
}else {
if(fpsLimit <= 0) {
syncTimer[0] = 0l;
if(fpsLimit <= 0 || fpsLimit > 1000) {
syncTimer = 0.0;
PlatformRuntime.swapDelayTeaVM();
}else {
if(!Display.sync(fpsLimit, syncTimer)) {
double frameMillis = (1000.0 / fpsLimit);
if(syncTimer == 0.0) {
syncTimer = PlatformRuntime.steadyTimeMillisTeaVM() + frameMillis;
PlatformRuntime.swapDelayTeaVM();
}else {
double millis = PlatformRuntime.steadyTimeMillisTeaVM();
int remaining = (int)(syncTimer - millis);
if(remaining > 0) {
if(!PlatformRuntime.useDelayOnSwap && PlatformRuntime.immediateContinueSupport) {
PlatformRuntime.immediateContinue(); // cannot stack setTimeouts, or it will throttle
millis = PlatformRuntime.steadyTimeMillisTeaVM();
remaining = (int)(syncTimer - millis);
if(remaining > 0) {
PlatformRuntime.sleep((int)remaining);
}
}else {
PlatformRuntime.sleep((int)remaining);
}
}else {
PlatformRuntime.swapDelayTeaVM();
}
millis = PlatformRuntime.steadyTimeMillisTeaVM();
if((syncTimer += frameMillis) < millis) {
syncTimer = millis;
}
}
}
}
}else {
syncTimer[0] = 0l;
EagUtils.sleep(50);
syncTimer = 0.0;
PlatformRuntime.sleep(50);
}
}
@ -1579,7 +1600,7 @@ public class PlatformInput {
EarlyLoadScreen.paintEnable(PlatformOpenGL.checkVAOCapable(), allowBootMenu);
while(mouseEvents.isEmpty() && keyEvents.isEmpty() && touchEvents.isEmpty()) {
EagUtils.sleep(100);
PlatformRuntime.sleep(100);
}
}
}
@ -1864,7 +1885,7 @@ public class PlatformInput {
if(touchKeyboardField != null) {
touchKeyboardField.blur();
touchKeyboardField.setValue("");
EagUtils.sleep(10);
PlatformRuntime.sleep(10);
if(touchKeyboardForm != null) {
touchKeyboardForm.removeChild(touchKeyboardField);
}else {
@ -2135,7 +2156,7 @@ public class PlatformInput {
touchKeyboardField.blur();
touchKeyboardField.setValue("");
if(sync) {
EagUtils.sleep(10);
PlatformRuntime.sleep(10);
if(touchKeyboardForm != null) {
touchKeyboardForm.removeChild(touchKeyboardField);
}else {

View File

@ -766,6 +766,10 @@ public class PlatformRuntime {
}
}
public static boolean immediateContinueSupported() {
return immediateContinueSupport;
}
@Async
private static native void immediateContinueTeaVM0();
@ -1101,6 +1105,10 @@ public class PlatformRuntime {
@JSBody(params = { "steadyTimeFunc" }, script = "return steadyTimeFunc();")
private static native double steadyTimeMillis0(JSObject steadyTimeFunc);
public static double steadyTimeMillisTeaVM() {
return steadyTimeMillis0(steadyTimeFunc);
}
public static long steadyTimeMillis() {
return (long)steadyTimeMillis0(steadyTimeFunc);
}

View File

@ -111,6 +111,7 @@ public class PlatformVoiceClient {
if(!PlatformWebRTC.hasCheckedSupport) PlatformWebRTC.supported();
switch(PlatformWebRTC.supportedImpl) {
case PlatformWebRTC.WEBRTC_SUPPORT_CORE:
case PlatformWebRTC.WEBRTC_SUPPORT_CORE_NON_PROMISING:
case PlatformWebRTC.WEBRTC_SUPPORT_WEBKIT:
addCoreIceCandidate(peerConnection, str);
break;

View File

@ -49,8 +49,18 @@ public class PlatformWebRTC {
static final int WEBRTC_SUPPORT_CORE = 1;
static final int WEBRTC_SUPPORT_WEBKIT = 2;
static final int WEBRTC_SUPPORT_MOZ = 3;
static final int WEBRTC_SUPPORT_CORE_NON_PROMISING = 4;
@JSBody(script = "return (typeof RTCPeerConnection !== \"undefined\") ? 1 : ((typeof webkitRTCPeerConnection !== \"undefined\") ? 2 : ((typeof mozRTCPeerConnection !== \"undefined\") ? 3 : 0));")
@JSBody(script = "var checkPromising = function() { try {"
+ "return (typeof (new RTCPeerConnection({iceServers:[{urls:\"stun:127.69.0.1:6969\"}]})).createOffer() === \"object\") ? 1 : 4;"
+ "} catch(ex) {"
+ "return (ex.name === \"TypeError\") ? 4 : 1;"
+ "}};"
+ "return (typeof RTCPeerConnection !== \"undefined\")"
+ " ? checkPromising()"
+ " : ((typeof webkitRTCPeerConnection !== \"undefined\") ? 2"
+ " : ((typeof mozRTCPeerConnection !== \"undefined\") ? 3"
+ " : 0));")
private static native int checkSupportedImpl();
static boolean hasCheckedSupport = false;
@ -69,6 +79,8 @@ public class PlatformWebRTC {
logger.info("Using webkit- prefix for RTCPeerConnection");
}else if(supportedImpl == WEBRTC_SUPPORT_MOZ) {
logger.info("Using moz- prefix for RTCPeerConnection");
}else if(supportedImpl == WEBRTC_SUPPORT_CORE_NON_PROMISING) {
logger.info("Using non-promising RTCPeerConnection");
}
if(supportedImpl != WEBRTC_SUPPORT_NONE) {
belowChrome71Fix = isChromeBelow71();
@ -160,6 +172,7 @@ public class PlatformWebRTC {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
return createCoreRTCPeerConnection(iceServers);
case WEBRTC_SUPPORT_WEBKIT:
return createWebkitRTCPeerConnection(iceServers);
@ -191,11 +204,49 @@ public class PlatformWebRTC {
@JSBody(params = { "item" }, script = "return item.channel;")
static native JSObject getChannel(JSObject item);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createOffer().then(h1).catch(h2);")
private static native void createOfferPromising(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createOffer(h1, h2);")
static native void createOffer(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
private static native void createOfferLegacy(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
static void createOffer(JSObject peerConnection, DescHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
createOfferPromising(peerConnection, h1, h2);
break;
case WEBRTC_SUPPORT_WEBKIT:
case WEBRTC_SUPPORT_MOZ:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
createOfferLegacy(peerConnection, h1, h2);
break;
default:
throw new UnsupportedOperationException();
}
}
@JSBody(params = { "peerConnection", "desc", "h1", "h2" }, script = "peerConnection.setLocalDescription(desc).then(h1).catch(h2);")
private static native void setLocalDescriptionPromising(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "desc", "h1", "h2" }, script = "peerConnection.setLocalDescription(desc, h1, h2);")
static native void setLocalDescription(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2);
private static native void setLocalDescriptionLegacy(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2);
static void setLocalDescription(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
setLocalDescriptionPromising(peerConnection, desc, h1, h2);
break;
case WEBRTC_SUPPORT_WEBKIT:
case WEBRTC_SUPPORT_MOZ:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
setLocalDescriptionLegacy(peerConnection, desc, h1, h2);
break;
default:
throw new UnsupportedOperationException();
}
}
@JSBody(params = { "peerConnection", "str" }, script = "var candidateList = JSON.parse(str); for (var i = 0; i < candidateList.length; ++i) { peerConnection.addIceCandidate(new RTCIceCandidate(candidateList[i])); }; return null;")
private static native void addCoreIceCandidates(JSObject peerConnection, String str);
@ -219,6 +270,7 @@ public class PlatformWebRTC {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
case WEBRTC_SUPPORT_WEBKIT:
addCoreIceCandidates(peerConnection, str);
break;
@ -246,6 +298,7 @@ public class PlatformWebRTC {
}
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
if(useSessionDescConstructor) {
setCoreRemoteDescriptionLegacy(peerConnection, str);
}else {
@ -267,14 +320,20 @@ public class PlatformWebRTC {
}
}
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "try { peerConnection.setRemoteDescription(str).then(h1).catch(h2); return true; } catch(ex) { if(ex.name === \"TypeError\") return false; else throw ex; }")
private static native boolean setCoreRemoteDescription2Promising(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "try { peerConnection.setRemoteDescription(str, h1, h2); return true; } catch(ex) { if(ex.name === \"TypeError\") return false; else throw ex; }")
private static native boolean setCoreRemoteDescription2(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
private static native boolean setCoreRemoteDescription2Legacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "peerConnection.setRemoteDescription(new RTCSessionDescription(str)).then(h1).catch(h2);")
private static native void setCoreRemoteDescription2PromisingLegacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "peerConnection.setRemoteDescription(new RTCSessionDescription(str), h1, h2);")
private static native void setCoreRemoteDescription2Legacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
private static native void setCoreRemoteDescription2LegacyLegacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "peerConnection.setRemoteDescription(new mozRTCSessionDescription(str), h1, h2);")
private static native void setMozRemoteDescription2Legacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
private static native void setMozRemoteDescription2LegacyLegacy(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2);
static void setRemoteDescription2(JSObject peerConnection, JSObject str, EmptyHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
@ -284,20 +343,31 @@ public class PlatformWebRTC {
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
if(useSessionDescConstructor) {
setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2);
setCoreRemoteDescription2PromisingLegacy(peerConnection, str, h1, h2);
}else {
if(!setCoreRemoteDescription2(peerConnection, str, h1, h2)) {
if(!setCoreRemoteDescription2Promising(peerConnection, str, h1, h2)) {
useSessionDescConstructor = true;
logger.info("Note: Caught suspicious exception, using legacy RTCSessionDescription method");
setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2);
setCoreRemoteDescription2PromisingLegacy(peerConnection, str, h1, h2);
}
}
break;
case WEBRTC_SUPPORT_WEBKIT:
setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2);
setCoreRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
break;
case WEBRTC_SUPPORT_MOZ:
setMozRemoteDescription2Legacy(peerConnection, str, h1, h2);
setMozRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
break;
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
if(useSessionDescConstructor) {
setCoreRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
}else {
if(!setCoreRemoteDescription2Legacy(peerConnection, str, h1, h2)) {
useSessionDescConstructor = true;
logger.info("Note: Caught suspicious exception, using legacy RTCSessionDescription method");
setCoreRemoteDescription2LegacyLegacy(peerConnection, str, h1, h2);
}
}
break;
default:
throw new UnsupportedOperationException();
@ -312,8 +382,27 @@ public class PlatformWebRTC {
+ "}")
private static native void removeExtmapAllowMixed(JSObject objIn);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createAnswer().then(h1).catch(h2);")
private static native void createAnswerPromising(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
@JSBody(params = { "peerConnection", "h1", "h2" }, script = "peerConnection.createAnswer(h1, h2);")
static native void createAnswer(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
private static native void createAnswerLegacy(JSObject peerConnection, DescHandler h1, ErrorHandler h2);
static void createAnswer(JSObject peerConnection, DescHandler h1, ErrorHandler h2) {
if(!hasCheckedSupport) supported();
switch(supportedImpl) {
case WEBRTC_SUPPORT_CORE:
createAnswerPromising(peerConnection, h1, h2);
break;
case WEBRTC_SUPPORT_WEBKIT:
case WEBRTC_SUPPORT_MOZ:
case WEBRTC_SUPPORT_CORE_NON_PROMISING:
createAnswerLegacy(peerConnection, h1, h2);
break;
default:
throw new UnsupportedOperationException();
}
}
@JSBody(params = { "sock", "buffer" }, script = "sock.send(buffer);")
static native void nativeBinarySend(WebSocket sock, ArrayBuffer buffer);

View File

@ -8,7 +8,7 @@ import org.teavm.jso.typedarrays.Uint16Array;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -30,8 +30,14 @@ public class EaglerArrayBufferAllocator {
}
}
private static final ByteBuffer ZERO_LENGTH_BYTE_BUFFER = new EaglerArrayByteBuffer(Int8Array.create(0));
public static ByteBuffer allocateByteBuffer(int size) {
if(size != 0) {
return new EaglerArrayByteBuffer(Int8Array.create(size));
}else {
return ZERO_LENGTH_BYTE_BUFFER;
}
}
public static ByteBuffer wrapByteBufferTeaVM(DataView dv) {
@ -42,16 +48,28 @@ public class EaglerArrayBufferAllocator {
return new EaglerArrayByteBuffer(typedArray);
}
private static final IntBuffer ZERO_LENGTH_INT_BUFFER = new EaglerArrayIntBuffer(Int32Array.create(0));
public static IntBuffer allocateIntBuffer(int size) {
if(size != 0) {
return new EaglerArrayIntBuffer(Int32Array.create(size));
}else {
return ZERO_LENGTH_INT_BUFFER;
}
}
public static IntBuffer wrapIntBufferTeaVM(Int32Array typedArray) {
return new EaglerArrayIntBuffer(typedArray);
}
private static final FloatBuffer ZERO_LENGTH_FLOAT_BUFFER = new EaglerArrayFloatBuffer(Float32Array.create(0));
public static FloatBuffer allocateFloatBuffer(int size) {
if(size != 0) {
return new EaglerArrayFloatBuffer(Float32Array.create(size));
}else {
return ZERO_LENGTH_FLOAT_BUFFER;
}
}
public static FloatBuffer wrapFloatBufferTeaVM(Float32Array typedArray) {

View File

@ -41,6 +41,11 @@ addToLibrary({
return id;
},
resultFailed: function(msg) {
results = null;
epwFile = null;
setTimeout(unsetHeapViews, 20);
const parentElement = createCrashParentElement();
const messageContainer = document.createElement("div");
@ -85,40 +90,43 @@ addToLibrary({
for(var i = 0, j; i < numEPKs; ++i) {
j = idx + 11 + i * 3;
epkFiles[i] = {
data: results[HEAP32[j]],
name: results[HEAP32[j + 1]],
path: results[HEAP32[j + 2]]
"data": results[HEAP32[j]],
"name": results[HEAP32[j + 1]],
"path": results[HEAP32[j + 2]]
};
}
results.length = 0;
results = null;
epwFile = null;
window.__eaglercraftXLoaderContext = {
getEaglercraftXOpts: function() {
setTimeout(unsetHeapViews, 20);
window["__eaglercraftXLoaderContext"] = {
"getEaglercraftXOpts": function() {
return optsObj;
},
getEagRuntimeJSURL: function() {
"getEagRuntimeJSURL": function() {
return eagRuntimeJSURL;
},
getClassesWASMURL: function() {
"getClassesWASMURL": function() {
return classesWASMURL;
},
getClassesDeobfWASMURL: function() {
"getClassesDeobfWASMURL": function() {
return classesDeobfWASMURL;
},
getClassesTEADBGURL: function() {
"getClassesTEADBGURL": function() {
return classesDeobfTEADBGURL;
},
getEPKFiles: function() {
"getEPKFiles": function() {
return epkFiles;
},
getRootElement: function() {
"getRootElement": function() {
return rootElement;
},
getMainArgs: function() {
"getMainArgs": function() {
return [];
},
getImageURL: function(idx) {
"getImageURL": function(idx) {
switch(idx) {
case 0:
return splashURL;
@ -132,7 +140,7 @@ addToLibrary({
return null;
}
},
runMain: function(fn) {
"runMain": function(fn) {
setTimeout(fn, 10);
}
};
@ -152,6 +160,11 @@ addToLibrary({
const markupData = results[HEAP32[idx + 2]];
const markup = markupData ? UTF8Decoder.decode(markupData) : "<h1>Failed to load error screen</h1>";
results = null;
epwFile = null;
setTimeout(unsetHeapViews, 20);
const parentElement = createCrashParentElement();
const img = document.createElement("img");

View File

@ -14,20 +14,24 @@
*
*/
var loaderWASMPath = window["__eaglercraftXLoaderContextPre"]["loaderWASMURL"];
Module["locateFile"] = function(path) {
if(path === "loader.wasm") {
return window.__eaglercraftXLoaderContextPre.loaderWASMURL;
return loaderWASMPath;
}else {
return path;
}
};
const rootElement = window.__eaglercraftXLoaderContextPre.rootElement;
const optsObj = window.__eaglercraftXLoaderContextPre.eaglercraftXOpts;
const epwFile = window.__eaglercraftXLoaderContextPre.theEPWFileBuffer;
const splashURL = window.__eaglercraftXLoaderContextPre.splashURL;
var rootElement = window["__eaglercraftXLoaderContextPre"]["rootElement"];
var optsObj = window["__eaglercraftXLoaderContextPre"]["eaglercraftXOpts"];
var epwFile = window["__eaglercraftXLoaderContextPre"]["theEPWFileBuffer"];
var splashURL = window["__eaglercraftXLoaderContextPre"]["splashURL"];
const results = [ null ];
delete window["__eaglercraftXLoaderContextPre"];
var results = [ null ];
function createCrashParentElement() {
var oldSplash = null;
@ -59,3 +63,9 @@ function createCrashParentElement() {
return parentElement;
}
function unsetHeapViews() {
HEAP = HEAP8 = HEAPU8 = HEAP16 = HEAPU16 = HEAP32 = HEAPU32 = HEAPF32 = HEAPF64 = null;
wasmMemory = null;
Module = null;
}

View File

@ -464,6 +464,9 @@ public class PlatformRuntime {
@Import(module = "platformRuntime", name = "immediateContinue")
private static native void immediateContinue0();
@Import(module = "platformRuntime", name = "immediateContinueSupported")
public static native boolean immediateContinueSupported();
public static void postCreate() {
}

View File

@ -32,7 +32,7 @@ public class WASMGCBufferAllocator {
public static Address malloc(int size) {
if(size == 0) {
throw new IllegalArgumentException("Tried to allocate 0 bytes!");
return Address.fromInt(0);
}
Address addr;
if(enableBufferOverflowCheck) {
@ -55,11 +55,11 @@ public class WASMGCBufferAllocator {
}
public static Address calloc(int size) {
if(size == 0) {
return Address.fromInt(0);
}
Address addr;
if(enableBufferOverflowCheck) {
if(size == 0) {
throw new OutOfMemoryError("Tried to allocate 0 bytes!");
}
addr = DirectMalloc.calloc(size + 12);
if(addr.toInt() == 0) {
throw new OutOfMemoryError("DirectMalloc returned null pointer!");
@ -87,33 +87,55 @@ public class WASMGCBufferAllocator {
if(tag != ptr.add(size + 8).getInt()) {
throw new RuntimeException("Detected a buffer write overflow");
}
DirectMalloc.free(ptr);
}else {
}
DirectMalloc.free(ptr);
}
}
}
private static final ByteBuffer ZERO_LENGTH_BYTE_BUFFER = new DirectMallocByteBuffer(Address.fromInt(0), 0, true);
public static ByteBuffer allocateByteBuffer(int size) {
if(size != 0) {
return new DirectMallocByteBuffer(malloc(size), size, true);
}else {
return ZERO_LENGTH_BYTE_BUFFER;
}
}
private static final ShortBuffer ZERO_LENGTH_SHORT_BUFFER = new DirectMallocShortBuffer(Address.fromInt(0), 0, true);
public static ShortBuffer allocateShortBuffer(int size) {
if(size != 0) {
return new DirectMallocShortBuffer(malloc(size << 1), size, true);
}else {
return ZERO_LENGTH_SHORT_BUFFER;
}
}
private static final IntBuffer ZERO_LENGTH_INT_BUFFER = new DirectMallocIntBuffer(Address.fromInt(0), 0, true);
public static IntBuffer allocateIntBuffer(int size) {
if(size != 0) {
return new DirectMallocIntBuffer(malloc(size << 2), size, true);
}else {
return ZERO_LENGTH_INT_BUFFER;
}
}
private static final FloatBuffer ZERO_LENGTH_FLOAT_BUFFER = new DirectMallocFloatBuffer(Address.fromInt(0), 0, true);
public static FloatBuffer allocateFloatBuffer(int size) {
if(size != 0) {
return new DirectMallocFloatBuffer(malloc(size << 2), size, true);
}else {
return ZERO_LENGTH_FLOAT_BUFFER;
}
}
public static void freeByteBuffer(ByteBuffer buffer) {
DirectMallocByteBuffer buf = (DirectMallocByteBuffer)buffer;
if(buf.original) {
WASMGCBufferAllocator.free(buf.address);
free(buf.address);
}else {
throwNotOriginal(buf);
}
@ -122,7 +144,7 @@ public class WASMGCBufferAllocator {
public static void freeShortBuffer(ShortBuffer buffer) {
DirectMallocShortBuffer buf = (DirectMallocShortBuffer)buffer;
if(buf.original) {
WASMGCBufferAllocator.free(buf.address);
free(buf.address);
}else {
throwNotOriginal(buf);
}
@ -131,7 +153,7 @@ public class WASMGCBufferAllocator {
public static void freeIntBuffer(IntBuffer buffer) {
DirectMallocIntBuffer buf = (DirectMallocIntBuffer)buffer;
if(buf.original) {
WASMGCBufferAllocator.free(buf.address);
free(buf.address);
}else {
throwNotOriginal(buf);
}
@ -140,7 +162,7 @@ public class WASMGCBufferAllocator {
public static void freeFloatBuffer(FloatBuffer buffer) {
DirectMallocFloatBuffer buf = (DirectMallocFloatBuffer)buffer;
if(buf.original) {
WASMGCBufferAllocator.free(buf.address);
free(buf.address);
}else {
throwNotOriginal(buf);
}

View File

@ -1,7 +1,6 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import org.teavm.interop.Address;
import org.teavm.interop.DirectMalloc;
import org.teavm.jso.typedarrays.Float32Array;
import org.teavm.jso.typedarrays.Int16Array;
import org.teavm.jso.typedarrays.Int32Array;

View File

@ -28,6 +28,7 @@ async function entryPoint() {
crashURL = self.__eaglercraftXLoaderContext.getImageURL(2);
faviconURL = self.__eaglercraftXLoaderContext.getImageURL(3);
const args = self.__eaglercraftXLoaderContext.getMainArgs();
delete self.__eaglercraftXLoaderContext;
const isWorker = args[0] === "_worker_process_";
if(!isWorker) {

View File

@ -561,21 +561,39 @@ async function initPlatformInput(inputImports) {
* @return {Promise}
*/
function syncDelay(fpsLimit) {
if(fpsLimit > 0 && fpsLimit < 1000) {
if(manualSyncTimer === 0) {
manualSyncTimer = performance.now();
}else {
const millis = performance.now();
if(fpsLimit > 0 && fpsLimit <= 1000) {
const frameMillis = (1000 / fpsLimit);
var frameTime = millis - manualSyncTimer;
if(frameTime > 2000 || frameTime < 0) {
frameTime = frameMillis;
manualSyncTimer = millis;
if(manualSyncTimer === 0) {
manualSyncTimer = performance.now() + frameMillis;
}else {
manualSyncTimer += frameMillis;
var millis = performance.now();
var remaining = (manualSyncTimer - millis) | 0;
if(remaining > 0) {
if(!runtimeOpts.useDelayOnSwap && allowImmediateContinue) {
return immediateContinueImpl().then(function() {
var millis0 = performance.now();
var remaining0 = (manualSyncTimer - millis0) | 0;
if(remaining0 > 0) {
return sleepPromise(remaining0).then(function() {
var millis1 = performance.now();
if((manualSyncTimer += frameMillis) < millis1) {
manualSyncTimer = millis1;
}
if(frameTime >= 0 && frameTime < frameMillis) {
return sleepPromise(frameMillis - frameTime);
});
}else if((manualSyncTimer += frameMillis) < millis0) {
manualSyncTimer = millis0;
}
});
}else {
return sleepPromise(remaining).then(function() {
var millis0 = performance.now();
if((manualSyncTimer += frameMillis) < millis0) {
manualSyncTimer = millis0;
}
});
}
}else if((manualSyncTimer += frameMillis) < millis) {
manualSyncTimer = millis;
}
}
}else {

View File

@ -199,6 +199,13 @@ function swapDelayImpl() {
eagruntimeImpl.platformRuntime["immediateContinue"] = new WebAssembly.Suspending(immediateContinueImpl);
/**
* @return {boolean}
*/
eagruntimeImpl.platformRuntime["immediateContinueSupported"] = function() {
return allowImmediateContinue;
};
/**
* @param {number} id
* @param {string} str

View File

@ -5,5 +5,5 @@ call emcc -c -O3 ../src/wasm-gc-teavm-loader/c/main.c -o bin/emscripten/main.o
call emcc -c -O3 ../src/wasm-gc-teavm-loader/c/xz/xz_crc32.c -o bin/emscripten/xz_crc32.o
call emcc -c -O3 ../src/wasm-gc-teavm-loader/c/xz/xz_dec_lzma2.c -o bin/emscripten/xz_dec_lzma2.o
call emcc -c -O3 ../src/wasm-gc-teavm-loader/c/xz/xz_dec_stream.c -o bin/emscripten/xz_dec_stream.o
call emcc -O3 -sMALLOC=dlmalloc -sALLOW_MEMORY_GROWTH -sINITIAL_HEAP=16777216 -sMAXIMUM_MEMORY=67108864 --pre-js ../src/wasm-gc-teavm-loader/js/pre.js --js-library ../src/wasm-gc-teavm-loader/js/library.js bin/emscripten/main.o bin/emscripten/xz_crc32.o bin/emscripten/xz_dec_lzma2.o bin/emscripten/xz_dec_stream.o -o javascript/loader.js
call emcc -O3 -sMALLOC=dlmalloc -sALLOW_MEMORY_GROWTH -sINITIAL_HEAP=16777216 -sMAXIMUM_MEMORY=67108864 --closure 1 --closure-args=--isolation_mode=IIFE --closure-args=--emit_use_strict --pre-js ../src/wasm-gc-teavm-loader/js/pre.js --js-library ../src/wasm-gc-teavm-loader/js/library.js bin/emscripten/main.o bin/emscripten/xz_crc32.o bin/emscripten/xz_dec_lzma2.o bin/emscripten/xz_dec_stream.o -o javascript/loader.js
pause

View File

@ -4,4 +4,4 @@ emcc -c -O3 ../src/wasm-gc-teavm-loader/c/main.c -o bin/emscripten/main.o
emcc -c -O3 ../src/wasm-gc-teavm-loader/c/xz/xz_crc32.c -o bin/emscripten/xz_crc32.o
emcc -c -O3 ../src/wasm-gc-teavm-loader/c/xz/xz_dec_lzma2.c -o bin/emscripten/xz_dec_lzma2.o
emcc -c -O3 ../src/wasm-gc-teavm-loader/c/xz/xz_dec_stream.c -o bin/emscripten/xz_dec_stream.o
emcc -O3 -sMALLOC=dlmalloc -sALLOW_MEMORY_GROWTH -sINITIAL_HEAP=16777216 -sMAXIMUM_MEMORY=67108864 --pre-js ../src/wasm-gc-teavm-loader/js/pre.js --js-library ../src/wasm-gc-teavm-loader/js/library.js bin/emscripten/main.o bin/emscripten/xz_crc32.o bin/emscripten/xz_dec_lzma2.o bin/emscripten/xz_dec_stream.o -o javascript/loader.js
emcc -O3 -sMALLOC=dlmalloc -sALLOW_MEMORY_GROWTH -sINITIAL_HEAP=16777216 -sMAXIMUM_MEMORY=67108864 --closure 1 --closure-args=--isolation_mode=IIFE --closure-args=--emit_use_strict --pre-js ../src/wasm-gc-teavm-loader/js/pre.js --js-library ../src/wasm-gc-teavm-loader/js/library.js bin/emscripten/main.o bin/emscripten/xz_crc32.o bin/emscripten/xz_dec_lzma2.o bin/emscripten/xz_dec_stream.o -o javascript/loader.js

View File

@ -1,8 +1,8 @@
client-version-integer=44
client-version-integer=45
client-package-name=net.lax1dude.eaglercraft.v1_8.client
client-origin-name=EaglercraftX
client-origin-version=u44
client-origin-version=u45
client-origin-vendor=lax1dude
client-fork-name=EaglercraftX
client-fork-version=u44
client-fork-version=u45
client-fork-vendor=lax1dude

File diff suppressed because one or more lines are too long