mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #0 - First Release
This commit is contained in:
@ -0,0 +1,81 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.minecraft;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.InstancedParticleRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.EntityFX;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class AcceleratedEffectRenderer implements IAcceleratedParticleEngine {
|
||||
|
||||
private float partialTicks;
|
||||
|
||||
private float f1;
|
||||
private float f2;
|
||||
private float f3;
|
||||
private float f4;
|
||||
private float f5;
|
||||
|
||||
public void begin(float partialTicks) {
|
||||
this.partialTicks = partialTicks;
|
||||
InstancedParticleRenderer.begin();
|
||||
Entity et = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if(et != null) {
|
||||
f1 = MathHelper.cos(et.rotationYaw * 0.017453292F);
|
||||
f2 = MathHelper.sin(et.rotationYaw * 0.017453292F);
|
||||
f3 = -f2 * MathHelper.sin(et.rotationPitch * 0.017453292F);
|
||||
f4 = f1 * MathHelper.sin(et.rotationPitch * 0.017453292F);
|
||||
f5 = MathHelper.cos(et.rotationPitch * 0.017453292F);
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(float texCoordWidth, float texCoordHeight) {
|
||||
InstancedParticleRenderer.render(texCoordWidth, texCoordHeight, 0.0625f, f1, f5, f2, f3, f4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY, int lightMapData,
|
||||
int texSize, float particleSize, float r, float g, float b, float a) {
|
||||
float xx = (float) (entityIn.prevPosX + (entityIn.posX - entityIn.prevPosX) * (double) partialTicks - EntityFX.interpPosX);
|
||||
float yy = (float) (entityIn.prevPosY + (entityIn.posY - entityIn.prevPosY) * (double) partialTicks - EntityFX.interpPosY);
|
||||
float zz = (float) (entityIn.prevPosZ + (entityIn.posZ - entityIn.prevPosZ) * (double) partialTicks - EntityFX.interpPosZ);
|
||||
drawParticle(xx, yy, zz, particleIndexX, particleIndexY, lightMapData, texSize, particleSize, r, g, b, a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY, int lightMapData,
|
||||
int texSize, float particleSize, int rgba) {
|
||||
float xx = (float) (entityIn.prevPosX + (entityIn.posX - entityIn.prevPosX) * (double) partialTicks - EntityFX.interpPosX);
|
||||
float yy = (float) (entityIn.prevPosY + (entityIn.posY - entityIn.prevPosY) * (double) partialTicks - EntityFX.interpPosY);
|
||||
float zz = (float) (entityIn.prevPosZ + (entityIn.posZ - entityIn.prevPosZ) * (double) partialTicks - EntityFX.interpPosZ);
|
||||
drawParticle(xx, yy, zz, particleIndexX, particleIndexY, lightMapData, texSize, particleSize, rgba);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a) {
|
||||
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
|
||||
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, r, g, b, a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, int rgba) {
|
||||
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
|
||||
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, rgba);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.minecraft;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.WorldVertexBufferUploader;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RegionRenderCacheBuilder;
|
||||
import net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator;
|
||||
import net.minecraft.client.renderer.chunk.CompiledChunk;
|
||||
import net.minecraft.client.renderer.chunk.ListedRenderChunk;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.EnumWorldBlockLayer;
|
||||
|
||||
public class ChunkUpdateManager {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private final WorldVertexBufferUploader worldVertexUploader;
|
||||
private final RegionRenderCacheBuilder renderCache;
|
||||
|
||||
private int chunkUpdatesTotal = 0;
|
||||
private int chunkUpdatesTotalLast = 0;
|
||||
private int chunkUpdatesTotalImmediate = 0;
|
||||
private int chunkUpdatesTotalImmediateLast = 0;
|
||||
private int chunkUpdatesQueued = 0;
|
||||
private int chunkUpdatesQueuedLast = 0;
|
||||
private long chunkUpdatesTotalLastUpdate = 0l;
|
||||
|
||||
private final List<ChunkCompileTaskGenerator> queue = new LinkedList();
|
||||
|
||||
public ChunkUpdateManager() {
|
||||
worldVertexUploader = new WorldVertexBufferUploader();
|
||||
renderCache = new RegionRenderCacheBuilder();
|
||||
}
|
||||
|
||||
public static class EmptyBlockLayerException extends IllegalStateException {
|
||||
}
|
||||
|
||||
private void runGenerator(ChunkCompileTaskGenerator generator, Entity entity) {
|
||||
generator.setRegionRenderCacheBuilder(renderCache);
|
||||
float f = (float) entity.posX;
|
||||
float f1 = (float) entity.posY + entity.getEyeHeight();
|
||||
float f2 = (float) entity.posZ;
|
||||
ChunkCompileTaskGenerator.Type chunkcompiletaskgenerator$type = generator.getType();
|
||||
generator.setStatus(ChunkCompileTaskGenerator.Status.COMPILING);
|
||||
if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.REBUILD_CHUNK) {
|
||||
generator.getRenderChunk().rebuildChunk(f, f1, f2, generator);
|
||||
} else if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.RESORT_TRANSPARENCY) {
|
||||
RenderChunk r = generator.getRenderChunk();
|
||||
try {
|
||||
r.resortTransparency(f, f1, f2, generator);
|
||||
if(generator.getCompiledChunk().isLayerEmpty(EnumWorldBlockLayer.TRANSLUCENT)) {
|
||||
throw new EmptyBlockLayerException();
|
||||
}
|
||||
}catch(EmptyBlockLayerException ex) {
|
||||
LOGGER.error("RenderChunk {} tried to update it's TRANSLUCENT layer with no proper initialization", r.getPosition());
|
||||
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
|
||||
return; // rip
|
||||
}
|
||||
}
|
||||
|
||||
generator.setStatus(ChunkCompileTaskGenerator.Status.UPLOADING);
|
||||
|
||||
final CompiledChunk compiledchunk = generator.getCompiledChunk();
|
||||
if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.REBUILD_CHUNK) {
|
||||
for (EnumWorldBlockLayer enumworldblocklayer : EnumWorldBlockLayer.values()) {
|
||||
if (!compiledchunk.isLayerEmpty(enumworldblocklayer)) {
|
||||
this.uploadChunk(enumworldblocklayer,
|
||||
generator.getRegionRenderCacheBuilder().getWorldRendererByLayer(enumworldblocklayer),
|
||||
generator.getRenderChunk(), compiledchunk);
|
||||
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
|
||||
}
|
||||
}
|
||||
generator.getRenderChunk().setCompiledChunk(compiledchunk);
|
||||
} else if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.RESORT_TRANSPARENCY) {
|
||||
this.uploadChunk(EnumWorldBlockLayer.TRANSLUCENT, generator.getRegionRenderCacheBuilder()
|
||||
.getWorldRendererByLayer(EnumWorldBlockLayer.TRANSLUCENT),
|
||||
generator.getRenderChunk(), compiledchunk);
|
||||
generator.getRenderChunk().setCompiledChunk(compiledchunk);
|
||||
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateChunks(long timeout) {
|
||||
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if (entity == null) {
|
||||
queue.clear();
|
||||
chunkUpdatesQueued = 0;
|
||||
return false;
|
||||
}else {
|
||||
boolean flag = false;
|
||||
long millis = System.currentTimeMillis();
|
||||
List<ChunkCompileTaskGenerator> droppedUpdates = new LinkedList();
|
||||
while(!queue.isEmpty()) {
|
||||
ChunkCompileTaskGenerator generator = queue.remove(0);
|
||||
|
||||
if(!generator.canExecuteYet()) {
|
||||
if(millis - generator.goddamnFuckingTimeout < 60000l) {
|
||||
droppedUpdates.add(generator);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
runGenerator(generator, entity);
|
||||
flag = true;
|
||||
|
||||
++chunkUpdatesTotal;
|
||||
|
||||
if(timeout < System.nanoTime()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
queue.addAll(droppedUpdates);
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateChunkLater(RenderChunk chunkRenderer) {
|
||||
final ChunkCompileTaskGenerator chunkcompiletaskgenerator = chunkRenderer.makeCompileTaskChunk();
|
||||
boolean flag = queue.size() < 100;
|
||||
if (!flag) {
|
||||
chunkcompiletaskgenerator.finish();
|
||||
}else {
|
||||
chunkcompiletaskgenerator.addFinishRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(queue.remove(chunkcompiletaskgenerator)) {
|
||||
++chunkUpdatesTotal;
|
||||
}
|
||||
}
|
||||
});
|
||||
queue.add(chunkcompiletaskgenerator);
|
||||
++chunkUpdatesQueued;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public boolean updateChunkNow(RenderChunk chunkRenderer) {
|
||||
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if (entity != null) {
|
||||
runGenerator(chunkRenderer.makeCompileTaskChunk(), entity);
|
||||
++chunkUpdatesTotalImmediate;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void stopChunkUpdates() {
|
||||
queue.clear();
|
||||
chunkUpdatesQueued = 0;
|
||||
}
|
||||
|
||||
public boolean updateTransparencyLater(RenderChunk chunkRenderer) {
|
||||
if(isAlreadyQueued(chunkRenderer)) {
|
||||
return true;
|
||||
}
|
||||
final ChunkCompileTaskGenerator chunkcompiletaskgenerator = chunkRenderer.makeCompileTaskTransparency();
|
||||
if (chunkcompiletaskgenerator == null) {
|
||||
return true;
|
||||
}
|
||||
chunkcompiletaskgenerator.goddamnFuckingTimeout = System.currentTimeMillis();
|
||||
if(queue.size() < 100) {
|
||||
chunkcompiletaskgenerator.addFinishRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(queue.remove(chunkcompiletaskgenerator)) {
|
||||
++chunkUpdatesTotal;
|
||||
}
|
||||
}
|
||||
});
|
||||
queue.add(chunkcompiletaskgenerator);
|
||||
++chunkUpdatesQueued;
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void uploadChunk(final EnumWorldBlockLayer player, final WorldRenderer chunkRenderer,
|
||||
final RenderChunk compiledChunkIn, final CompiledChunk parCompiledChunk) {
|
||||
this.uploadDisplayList(chunkRenderer,
|
||||
((ListedRenderChunk) compiledChunkIn).getDisplayList(player, parCompiledChunk), compiledChunkIn);
|
||||
chunkRenderer.setTranslation(0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
||||
private void uploadDisplayList(WorldRenderer chunkRenderer, int parInt1, RenderChunk parRenderChunk) {
|
||||
EaglercraftGPU.glNewList(parInt1, GL_COMPILE);
|
||||
GlStateManager.pushMatrix();
|
||||
this.worldVertexUploader.func_181679_a(chunkRenderer);
|
||||
GlStateManager.popMatrix();
|
||||
EaglercraftGPU.glEndList();
|
||||
}
|
||||
|
||||
public boolean isAlreadyQueued(RenderChunk update) {
|
||||
for(int i = 0, l = queue.size(); i < l; ++i) {
|
||||
if(queue.get(i).getRenderChunk() == update) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDebugInfo() {
|
||||
long millis = System.currentTimeMillis();
|
||||
|
||||
if(millis - chunkUpdatesTotalLastUpdate > 500l) {
|
||||
chunkUpdatesTotalLastUpdate = millis;
|
||||
chunkUpdatesTotalLast = chunkUpdatesTotal;
|
||||
chunkUpdatesTotalImmediateLast = chunkUpdatesTotalImmediate;
|
||||
chunkUpdatesTotalImmediate = 0;
|
||||
chunkUpdatesTotal = 0;
|
||||
chunkUpdatesQueuedLast = chunkUpdatesQueued;
|
||||
chunkUpdatesQueued -= chunkUpdatesTotalLast;
|
||||
if(chunkUpdatesQueued < 0) {
|
||||
chunkUpdatesQueued = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return "Uq: " + (chunkUpdatesTotalLast + chunkUpdatesTotalImmediateLast) + "/"
|
||||
+ (chunkUpdatesQueuedLast + chunkUpdatesTotalImmediateLast);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.minecraft;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.InstancedFontRenderer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class EaglerFontRenderer extends FontRenderer {
|
||||
|
||||
private final int[] temporaryCodepointArray = new int[6553];
|
||||
|
||||
public EaglerFontRenderer(GameSettings gameSettingsIn, ResourceLocation location, TextureManager textureManagerIn,
|
||||
boolean unicode) {
|
||||
super(gameSettingsIn, location, textureManagerIn, unicode);
|
||||
}
|
||||
|
||||
public int drawString(String text, float x, float y, int color, boolean dropShadow) {
|
||||
if (text == null || text.length() == 0) {
|
||||
this.posX = x + (dropShadow ? 1 : 0);
|
||||
this.posY = y;
|
||||
} else {
|
||||
if(this.unicodeFlag || !decodeASCIICodepointsAndValidate(text)) {
|
||||
return super.drawString(text, x, y, color, dropShadow);
|
||||
}
|
||||
this.resetStyles();
|
||||
if ((color & 0xFC000000) == 0) {
|
||||
color |= 0xFF000000;
|
||||
}
|
||||
this.red = (float) (color >> 16 & 255) / 255.0F;
|
||||
this.blue = (float) (color >> 8 & 255) / 255.0F;
|
||||
this.green = (float) (color & 255) / 255.0F;
|
||||
this.alpha = (float) (color >> 24 & 255) / 255.0F;
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.textColor = color;
|
||||
this.renderStringAtPos0(text, dropShadow);
|
||||
}
|
||||
return (int) this.posX;
|
||||
}
|
||||
|
||||
protected void renderStringAtPos(String parString1, boolean parFlag) {
|
||||
if(parString1 == null) return;
|
||||
if(this.unicodeFlag || !decodeASCIICodepointsAndValidate(parString1)) {
|
||||
super.renderStringAtPos(parString1, parFlag);
|
||||
}else {
|
||||
renderStringAtPos0(parString1, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderStringAtPos0(String parString1, boolean parFlag) {
|
||||
renderEngine.bindTexture(locationFontTexture);
|
||||
InstancedFontRenderer.begin();
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
|
||||
worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
|
||||
|
||||
boolean hasStrike = false;
|
||||
|
||||
for (int i = 0; i < parString1.length(); ++i) {
|
||||
char c0 = parString1.charAt(i);
|
||||
if (c0 == 167 && i + 1 < parString1.length()) {
|
||||
int i1 = "0123456789abcdefklmnor".indexOf(Character.toLowerCase(parString1.charAt(i + 1)));
|
||||
if (i1 < 16) {
|
||||
this.randomStyle = false;
|
||||
this.boldStyle = false;
|
||||
this.strikethroughStyle = false;
|
||||
this.underlineStyle = false;
|
||||
this.italicStyle = false;
|
||||
if (i1 < 0 || i1 > 15) {
|
||||
i1 = 15;
|
||||
}
|
||||
int j1 = this.colorCode[i1];
|
||||
this.textColor = j1 | (this.textColor & 0xFF000000);
|
||||
} else if (i1 == 16) {
|
||||
this.randomStyle = true;
|
||||
} else if (i1 == 17) {
|
||||
this.boldStyle = true;
|
||||
} else if (i1 == 18) {
|
||||
this.strikethroughStyle = true;
|
||||
} else if (i1 == 19) {
|
||||
this.underlineStyle = true;
|
||||
} else if (i1 == 20) {
|
||||
this.italicStyle = true;
|
||||
} else if (i1 == 21) {
|
||||
this.randomStyle = false;
|
||||
this.boldStyle = false;
|
||||
this.strikethroughStyle = false;
|
||||
this.underlineStyle = false;
|
||||
this.italicStyle = false;
|
||||
this.textColor = ((int) (this.alpha * 255.0f) << 24) | ((int) (this.red * 255.0f) << 16)
|
||||
| ((int) (this.green * 255.0f) << 8) | (int) (this.blue * 255.0f);
|
||||
}
|
||||
|
||||
++i;
|
||||
} else {
|
||||
int j = temporaryCodepointArray[i];
|
||||
|
||||
if (this.randomStyle && j != -1) {
|
||||
int k = this.getCharWidth(c0);
|
||||
String chars = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
|
||||
|
||||
char c1;
|
||||
while (true) {
|
||||
j = this.fontRandom.nextInt(chars.length());
|
||||
c1 = chars.charAt(j);
|
||||
if (k == this.getCharWidth(c1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c0 = c1;
|
||||
}
|
||||
|
||||
float f = this.appendCharToBuffer(j, this.textColor, this.boldStyle, this.italicStyle);
|
||||
|
||||
if (this.strikethroughStyle) {
|
||||
hasStrike = true;
|
||||
worldrenderer.pos((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D)
|
||||
.endVertex();
|
||||
worldrenderer
|
||||
.pos((double) (this.posX + f), (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D)
|
||||
.endVertex();
|
||||
worldrenderer.pos((double) (this.posX + f),
|
||||
(double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D).endVertex();
|
||||
worldrenderer
|
||||
.pos((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D)
|
||||
.endVertex();
|
||||
worldrenderer.putColor4(this.textColor);
|
||||
}
|
||||
|
||||
if (this.underlineStyle) {
|
||||
hasStrike = true;
|
||||
int l = this.underlineStyle ? -1 : 0;
|
||||
worldrenderer.pos((double) (this.posX + (float) l),
|
||||
(double) (this.posY + (float) this.FONT_HEIGHT), 0.0D).endVertex();
|
||||
worldrenderer.pos((double) (this.posX + f), (double) (this.posY + (float) this.FONT_HEIGHT), 0.0D)
|
||||
.endVertex();
|
||||
worldrenderer
|
||||
.pos((double) (this.posX + f), (double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D)
|
||||
.endVertex();
|
||||
worldrenderer.pos((double) (this.posX + (float) l),
|
||||
(double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D).endVertex();
|
||||
worldrenderer.putColor4(this.textColor);
|
||||
}
|
||||
|
||||
this.posX += (float) ((int) f);
|
||||
}
|
||||
}
|
||||
|
||||
float texScale = 0.0625f;
|
||||
|
||||
if(!hasStrike) {
|
||||
worldrenderer.finishDrawing();
|
||||
}
|
||||
|
||||
if(parFlag) {
|
||||
if(hasStrike) {
|
||||
GlStateManager.color(0.25f, 0.25f, 0.25f, 1.0f);
|
||||
GlStateManager.translate(1.0f, 1.0f, 0.0f);
|
||||
tessellator.draw();
|
||||
GlStateManager.translate(-1.0f, -1.0f, 0.0f);
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
InstancedFontRenderer.render(8, 8, texScale, texScale, true);
|
||||
EaglercraftGPU.renderAgain();
|
||||
}else {
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
InstancedFontRenderer.render(8, 8, texScale, texScale, true);
|
||||
}
|
||||
}else {
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if(hasStrike) {
|
||||
tessellator.draw();
|
||||
}
|
||||
InstancedFontRenderer.render(8, 8, texScale, texScale, false);
|
||||
}
|
||||
|
||||
if(parFlag) {
|
||||
this.posX += 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private float appendCharToBuffer(int parInt1, int color, boolean boldStyle, boolean italicStyle) {
|
||||
if (parInt1 == 32) {
|
||||
return 4.0f;
|
||||
}else {
|
||||
int i = parInt1 % 16;
|
||||
int j = parInt1 / 16;
|
||||
float w = this.charWidth[parInt1];
|
||||
if(boldStyle) {
|
||||
InstancedFontRenderer.appendBoldQuad((int)this.posX, (int)this.posY, i, j, color, italicStyle);
|
||||
++w;
|
||||
}else {
|
||||
InstancedFontRenderer.appendQuad((int)this.posX, (int)this.posY, i, j, color, italicStyle);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean decodeASCIICodepointsAndValidate(String str) {
|
||||
for(int i = 0, l = str.length(); i < l; ++i) {
|
||||
int j = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000\u00a7"
|
||||
.indexOf(str.charAt(i));
|
||||
if(j != -1) {
|
||||
temporaryCodepointArray[i] = j;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,355 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.minecraft;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.HString;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
import net.minecraft.client.renderer.texture.TextureClock;
|
||||
import net.minecraft.client.renderer.texture.TextureCompass;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.client.resources.data.AnimationFrame;
|
||||
import net.minecraft.client.resources.data.AnimationMetadataSection;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.util.ReportedException;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class EaglerTextureAtlasSprite {
|
||||
private final String iconName;
|
||||
protected List<int[][]> framesTextureData = Lists.newArrayList();
|
||||
protected int[][] interpolatedFrameData;
|
||||
private AnimationMetadataSection animationMetadata;
|
||||
private int cacheInterpolateSteps;
|
||||
protected boolean rotated;
|
||||
protected int originX;
|
||||
protected int originY;
|
||||
protected int width;
|
||||
protected int height;
|
||||
private float minU;
|
||||
private float maxU;
|
||||
private float minV;
|
||||
private float maxV;
|
||||
protected int frameCounter;
|
||||
protected int tickCounter;
|
||||
private static String locationNameClock = "builtin/clock";
|
||||
private static String locationNameCompass = "builtin/compass";
|
||||
|
||||
protected TextureAnimationCache animationCache = null;
|
||||
|
||||
public EaglerTextureAtlasSprite(String spriteName) {
|
||||
this.iconName = spriteName;
|
||||
}
|
||||
|
||||
public static EaglerTextureAtlasSprite makeAtlasSprite(ResourceLocation spriteResourceLocation) {
|
||||
String s = spriteResourceLocation.toString();
|
||||
return (EaglerTextureAtlasSprite) (locationNameClock.equals(s) ? new TextureClock(s)
|
||||
: (locationNameCompass.equals(s) ? new TextureCompass(s) : new EaglerTextureAtlasSprite(s)));
|
||||
}
|
||||
|
||||
public static void setLocationNameClock(String clockName) {
|
||||
locationNameClock = clockName;
|
||||
}
|
||||
|
||||
public static void setLocationNameCompass(String compassName) {
|
||||
locationNameCompass = compassName;
|
||||
}
|
||||
|
||||
public void initSprite(int inX, int inY, int originInX, int originInY, boolean rotatedIn) {
|
||||
this.originX = originInX;
|
||||
this.originY = originInY;
|
||||
this.rotated = rotatedIn;
|
||||
float f = (float) (0.009999999776482582D / (double) inX);
|
||||
float f1 = (float) (0.009999999776482582D / (double) inY);
|
||||
this.minU = (float) originInX / (float) ((double) inX) + f;
|
||||
this.maxU = (float) (originInX + this.width) / (float) ((double) inX) - f;
|
||||
this.minV = (float) originInY / (float) inY + f1;
|
||||
this.maxV = (float) (originInY + this.height) / (float) inY - f1;
|
||||
}
|
||||
|
||||
public void copyFrom(EaglerTextureAtlasSprite atlasSpirit) {
|
||||
this.originX = atlasSpirit.originX;
|
||||
this.originY = atlasSpirit.originY;
|
||||
this.width = atlasSpirit.width;
|
||||
this.height = atlasSpirit.height;
|
||||
this.rotated = atlasSpirit.rotated;
|
||||
this.minU = atlasSpirit.minU;
|
||||
this.maxU = atlasSpirit.maxU;
|
||||
this.minV = atlasSpirit.minV;
|
||||
this.maxV = atlasSpirit.maxV;
|
||||
}
|
||||
|
||||
public int getOriginX() {
|
||||
return this.originX;
|
||||
}
|
||||
|
||||
public int getOriginY() {
|
||||
return this.originY;
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public float getMinU() {
|
||||
return this.minU;
|
||||
}
|
||||
|
||||
public float getMaxU() {
|
||||
return this.maxU;
|
||||
}
|
||||
|
||||
public float getInterpolatedU(double u) {
|
||||
float f = this.maxU - this.minU;
|
||||
return this.minU + f * (float) u / 16.0F;
|
||||
}
|
||||
|
||||
public float getMinV() {
|
||||
return this.minV;
|
||||
}
|
||||
|
||||
public float getMaxV() {
|
||||
return this.maxV;
|
||||
}
|
||||
|
||||
public float getInterpolatedV(double v) {
|
||||
float f = this.maxV - this.minV;
|
||||
return this.minV + f * ((float) v / 16.0F);
|
||||
}
|
||||
|
||||
public String getIconName() {
|
||||
return this.iconName;
|
||||
}
|
||||
|
||||
public void updateAnimation() {
|
||||
if(animationCache == null) {
|
||||
throw new IllegalStateException("Animation cache for '" + this.iconName + "' was never baked!");
|
||||
}
|
||||
++this.tickCounter;
|
||||
if (this.tickCounter >= this.animationMetadata.getFrameTimeSingle(this.frameCounter)) {
|
||||
int i = this.animationMetadata.getFrameIndex(this.frameCounter);
|
||||
int j = this.animationMetadata.getFrameCount() == 0 ? this.framesTextureData.size()
|
||||
: this.animationMetadata.getFrameCount();
|
||||
this.frameCounter = (this.frameCounter + 1) % j;
|
||||
this.tickCounter = 0;
|
||||
int k = this.animationMetadata.getFrameIndex(this.frameCounter);
|
||||
if (i != k && k >= 0 && k < this.framesTextureData.size()) {
|
||||
animationCache.copyFrameLevelsToTex2D(k, this.originX, this.originY, this.width, this.height);
|
||||
}
|
||||
} else if (this.animationMetadata.isInterpolate()) {
|
||||
float f = 1.0f - (float) this.tickCounter / (float) this.animationMetadata.getFrameTimeSingle(this.frameCounter);
|
||||
int i = this.animationMetadata.getFrameIndex(this.frameCounter);
|
||||
int j = this.animationMetadata.getFrameCount() == 0 ? this.framesTextureData.size()
|
||||
: this.animationMetadata.getFrameCount();
|
||||
int k = this.animationMetadata.getFrameIndex((this.frameCounter + 1) % j);
|
||||
if (i != k && k >= 0 && k < this.framesTextureData.size()) {
|
||||
animationCache.copyInterpolatedFrameLevelsToTex2D(i, k, f, this.originX, this.originY, this.width, this.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int[][] getFrameTextureData(int index) {
|
||||
return (int[][]) this.framesTextureData.get(index);
|
||||
}
|
||||
|
||||
public int getFrameCount() {
|
||||
return this.framesTextureData.size();
|
||||
}
|
||||
|
||||
public void setIconWidth(int newWidth) {
|
||||
this.width = newWidth;
|
||||
}
|
||||
|
||||
public void setIconHeight(int newHeight) {
|
||||
this.height = newHeight;
|
||||
}
|
||||
|
||||
public void loadSprite(ImageData[] images, AnimationMetadataSection meta) throws IOException {
|
||||
this.resetSprite();
|
||||
int i = images[0].width;
|
||||
int j = images[0].height;
|
||||
this.width = i;
|
||||
this.height = j;
|
||||
int[][] aint = new int[images.length][];
|
||||
|
||||
for (int k = 0; k < images.length; ++k) {
|
||||
ImageData bufferedimage = images[k];
|
||||
if (bufferedimage != null) {
|
||||
if (k > 0 && (bufferedimage.width) != i >> k || bufferedimage.height != j >> k) {
|
||||
throw new RuntimeException(
|
||||
HString.format("Unable to load miplevel: %d, image is size: %dx%d, expected %dx%d",
|
||||
new Object[] { Integer.valueOf(k), Integer.valueOf(bufferedimage.width),
|
||||
Integer.valueOf(bufferedimage.height), Integer.valueOf(i >> k),
|
||||
Integer.valueOf(j >> k) }));
|
||||
}
|
||||
|
||||
aint[k] = new int[bufferedimage.width * bufferedimage.height];
|
||||
bufferedimage.getRGB(0, 0, bufferedimage.width, bufferedimage.height, aint[k], 0, bufferedimage.width);
|
||||
}
|
||||
}
|
||||
|
||||
if (meta == null) {
|
||||
if (j != i) {
|
||||
throw new RuntimeException("broken aspect ratio and not an animation");
|
||||
}
|
||||
|
||||
this.framesTextureData.add(aint);
|
||||
} else {
|
||||
int j1 = j / i;
|
||||
int k1 = i;
|
||||
int l = i;
|
||||
this.height = this.width;
|
||||
if (meta.getFrameCount() > 0) {
|
||||
Iterator iterator = meta.getFrameIndexSet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
int i1 = ((Integer) iterator.next()).intValue();
|
||||
if (i1 >= j1) {
|
||||
throw new RuntimeException("invalid frameindex " + i1);
|
||||
}
|
||||
|
||||
this.allocateFrameTextureData(i1);
|
||||
this.framesTextureData.set(i1, getFrameTextureData(aint, k1, l, i1));
|
||||
}
|
||||
|
||||
this.animationMetadata = meta;
|
||||
} else {
|
||||
ArrayList arraylist = Lists.newArrayList();
|
||||
|
||||
for (int l1 = 0; l1 < j1; ++l1) {
|
||||
this.framesTextureData.add(getFrameTextureData(aint, k1, l, l1));
|
||||
arraylist.add(new AnimationFrame(l1, -1));
|
||||
}
|
||||
|
||||
this.animationMetadata = new AnimationMetadataSection(arraylist, this.width, this.height,
|
||||
meta.getFrameTime(), meta.isInterpolate());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void generateMipmaps(int level) {
|
||||
ArrayList arraylist = Lists.newArrayList();
|
||||
|
||||
for (int i = 0; i < this.framesTextureData.size(); ++i) {
|
||||
final int[][] aint = (int[][]) this.framesTextureData.get(i);
|
||||
if (aint != null) {
|
||||
try {
|
||||
arraylist.add(TextureUtil.generateMipmapData(level, this.width, aint));
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Generating mipmaps for frame");
|
||||
CrashReportCategory crashreportcategory = crashreport.makeCategory("Frame being iterated");
|
||||
crashreportcategory.addCrashSection("Frame index", Integer.valueOf(i));
|
||||
crashreportcategory.addCrashSectionCallable("Frame sizes", new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for (int[] aint1 : aint) {
|
||||
if (stringbuilder.length() > 0) {
|
||||
stringbuilder.append(", ");
|
||||
}
|
||||
|
||||
stringbuilder.append(aint1 == null ? "null" : Integer.valueOf(aint1.length));
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
});
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setFramesTextureData(arraylist);
|
||||
this.bakeAnimationCache();
|
||||
}
|
||||
|
||||
public void bakeAnimationCache() {
|
||||
if(animationMetadata != null) {
|
||||
int mipLevels = framesTextureData.get(0).length;
|
||||
if(animationCache == null) {
|
||||
animationCache = new TextureAnimationCache(width, height, mipLevels);
|
||||
}
|
||||
animationCache.initialize(framesTextureData, animationMetadata.isInterpolate());
|
||||
}
|
||||
}
|
||||
|
||||
private void allocateFrameTextureData(int index) {
|
||||
if (this.framesTextureData.size() <= index) {
|
||||
for (int i = this.framesTextureData.size(); i <= index; ++i) {
|
||||
this.framesTextureData.add((int[][]) null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static int[][] getFrameTextureData(int[][] data, int rows, int columns, int parInt3) {
|
||||
int[][] aint = new int[data.length][];
|
||||
|
||||
for (int i = 0; i < data.length; ++i) {
|
||||
int[] aint1 = data[i];
|
||||
if (aint1 != null) {
|
||||
aint[i] = new int[(rows >> i) * (columns >> i)];
|
||||
System.arraycopy(aint1, parInt3 * aint[i].length, aint[i], 0, aint[i].length);
|
||||
}
|
||||
}
|
||||
|
||||
return aint;
|
||||
}
|
||||
|
||||
public void clearFramesTextureData() {
|
||||
this.framesTextureData.clear();
|
||||
if(this.animationCache != null) {
|
||||
this.animationCache.free();
|
||||
this.animationCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAnimationMetadata() {
|
||||
return this.animationMetadata != null;
|
||||
}
|
||||
|
||||
public void setFramesTextureData(List<int[][]> newFramesTextureData) {
|
||||
this.framesTextureData = newFramesTextureData;
|
||||
}
|
||||
|
||||
private void resetSprite() {
|
||||
this.animationMetadata = null;
|
||||
this.setFramesTextureData(Lists.newArrayList());
|
||||
this.frameCounter = 0;
|
||||
this.tickCounter = 0;
|
||||
if(this.animationCache != null) {
|
||||
this.animationCache.free();
|
||||
this.animationCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "TextureAtlasSprite{name=\'" + this.iconName + '\'' + ", frameCount=" + this.framesTextureData.size()
|
||||
+ ", rotated=" + this.rotated + ", x=" + this.originX + ", y=" + this.originY + ", height="
|
||||
+ this.height + ", width=" + this.width + ", u0=" + this.minU + ", u1=" + this.maxU + ", v0="
|
||||
+ this.minV + ", v1=" + this.maxV + '}';
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.minecraft;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public interface IAcceleratedParticleEngine {
|
||||
|
||||
void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a);
|
||||
|
||||
void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, int rgba);
|
||||
|
||||
void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a);
|
||||
|
||||
void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, int rgba);
|
||||
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.minecraft;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IFramebufferGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IRenderbufferGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.ITextureGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.SpriteLevelMixer;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class TextureAnimationCache {
|
||||
|
||||
public static final int _GL_FRAMEBUFFER = 0x8D40; // enum not defined in RealOpenGLEnums
|
||||
public static final int _GL_RENDERBUFFER = 0x8D41;
|
||||
public static final int _GL_COLOR_ATTACHMENT0 = 0x8CE0;
|
||||
|
||||
public final int width;
|
||||
public final int height;
|
||||
public final int mipLevels;
|
||||
|
||||
private int frameCount = 1;
|
||||
|
||||
private int[] cacheTextures = null;
|
||||
private IFramebufferGL[] cacheFramebuffers = null;
|
||||
|
||||
private IFramebufferGL interpolateFramebuffer = null;
|
||||
private IRenderbufferGL interpolateRenderbuffer = null;
|
||||
|
||||
public TextureAnimationCache(int width, int height, int mipLevels) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.mipLevels = mipLevels;
|
||||
}
|
||||
|
||||
public void initialize(List<int[][]> frames, boolean enableInterpolation) {
|
||||
boolean init = cacheTextures == null;
|
||||
if(init) {
|
||||
cacheTextures = new int[mipLevels];
|
||||
for(int i = 0; i < cacheTextures.length; ++i) {
|
||||
cacheTextures[i] = GlStateManager.generateTexture();
|
||||
GlStateManager.bindTexture(cacheTextures[i]);
|
||||
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
if(enableInterpolation) {
|
||||
interpolateFramebuffer = _wglCreateFramebuffer();
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, interpolateFramebuffer);
|
||||
interpolateRenderbuffer = _wglCreateRenderbuffer();
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, interpolateRenderbuffer);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, GL_RGBA8, width, height);
|
||||
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0,
|
||||
_GL_RENDERBUFFER, interpolateRenderbuffer);
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
|
||||
}
|
||||
}
|
||||
|
||||
frameCount = frames.size();
|
||||
IntBuffer pixels = GLAllocation.createDirectIntBuffer(width * height * frameCount);
|
||||
|
||||
try {
|
||||
for(int i = 0; i < mipLevels; ++i) {
|
||||
pixels.clear();
|
||||
|
||||
int lw = width >> i;
|
||||
int lh = height >> i;
|
||||
int tileLength = lw * lh;
|
||||
|
||||
for(int j = 0; j < frameCount; ++j) {
|
||||
int[][] frame = frames.get(j);
|
||||
if(frame.length <= i) {
|
||||
throw new IllegalArgumentException("Frame #" + j + " only has " + frame.length + " mipmap levels! (" + mipLevels + " were expected)");
|
||||
}
|
||||
|
||||
int[] frameLevel = frame[i];
|
||||
if(frameLevel.length != tileLength) {
|
||||
throw new IllegalArgumentException("Frame #" + j + " level " + i + " is " + frameLevel.length + " pixels large! (" + tileLength + " expected)");
|
||||
}
|
||||
|
||||
pixels.put(frameLevel);
|
||||
}
|
||||
|
||||
pixels.flip();
|
||||
|
||||
GlStateManager.bindTexture(cacheTextures[i]);
|
||||
EaglercraftGPU.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, lw, lh * frameCount, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
}
|
||||
}finally {
|
||||
EagRuntime.freeIntBuffer(pixels);
|
||||
}
|
||||
|
||||
if(init) {
|
||||
cacheFramebuffers = new IFramebufferGL[mipLevels];
|
||||
for(int i = 0; i < mipLevels; ++i) {
|
||||
GlStateManager.bindTexture(cacheTextures[i]);
|
||||
IFramebufferGL fbo = _wglCreateFramebuffer();
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, fbo);
|
||||
_wglFramebufferTexture2D(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
EaglercraftGPU.getNativeTexture(cacheTextures[i]), 0);
|
||||
cacheFramebuffers[i] = fbo;
|
||||
}
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void free() {
|
||||
if(cacheTextures != null) {
|
||||
if(interpolateFramebuffer != null) {
|
||||
_wglDeleteFramebuffer(interpolateFramebuffer);
|
||||
interpolateFramebuffer = null;
|
||||
}
|
||||
if(interpolateRenderbuffer != null) {
|
||||
_wglDeleteRenderbuffer(interpolateRenderbuffer);
|
||||
interpolateRenderbuffer = null;
|
||||
}
|
||||
if(cacheFramebuffers != null) {
|
||||
for(int i = 0; i < mipLevels; ++i) {
|
||||
_wglDeleteFramebuffer(cacheFramebuffers[i]);
|
||||
}
|
||||
cacheFramebuffers = null;
|
||||
}
|
||||
for(int i = 0; i < cacheTextures.length; ++i) {
|
||||
GlStateManager.deleteTexture(cacheTextures[i]);
|
||||
}
|
||||
cacheTextures = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void copyFrameLevelsToTex2D(int animationFrame, int dx, int dy, int w, int h) {
|
||||
copyFrameLevelsToTex2D(animationFrame, mipLevels, dx, dy, w, h);
|
||||
}
|
||||
|
||||
public void copyFrameLevelsToTex2D(int animationFrame, int levels, int dx, int dy, int w, int h) {
|
||||
for(int i = 0; i < levels; ++i) {
|
||||
copyFrameToTex2D(animationFrame, i, dx >> i, dy >> i, w >> i, h >> i);
|
||||
}
|
||||
}
|
||||
|
||||
public void copyFrameToTex2D(int animationFrame, int level, int dx, int dy, int w, int h) {
|
||||
if(cacheTextures == null) {
|
||||
throw new IllegalStateException("Cannot copy from uninitialized TextureAnimationCache");
|
||||
}
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, cacheFramebuffers[level]);
|
||||
_wglReadBuffer(_GL_COLOR_ATTACHMENT0);
|
||||
_wglCopyTexSubImage2D(GL_TEXTURE_2D, level, dx, dy, 0, h * animationFrame, w, h);
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int dx,
|
||||
int dy, int w, int h) {
|
||||
copyInterpolatedFrameLevelsToTex2D(animationFrameFrom, animationFrameTo, factor, mipLevels, dx, dy, w, h);
|
||||
}
|
||||
|
||||
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor,
|
||||
int levels, int dx, int dy, int w, int h) {
|
||||
for(int i = 0; i < levels; ++i) {
|
||||
copyInterpolatedFrameToTex2D(animationFrameFrom, animationFrameTo, factor, i, dx >> i, dy >> i, w >> i, h >> i);
|
||||
}
|
||||
}
|
||||
|
||||
public void copyInterpolatedFrameToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int level,
|
||||
int dx, int dy, int w, int h) {
|
||||
if(cacheTextures == null) {
|
||||
throw new IllegalStateException("Cannot copy from uninitialized TextureAnimationCache");
|
||||
}
|
||||
|
||||
int storeTexture = GlStateManager.getTextureBound();
|
||||
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, interpolateFramebuffer);
|
||||
GlStateManager.bindTexture(cacheTextures[level]);
|
||||
|
||||
int[] storeViewport = new int[4];
|
||||
EaglercraftGPU.glGetInteger(GL_VIEWPORT, storeViewport);
|
||||
GlStateManager.viewport(0, 0, w, h);
|
||||
GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
GlStateManager.clear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
Matrix3f matrix = new Matrix3f();
|
||||
matrix.m11 = 1.0f / frameCount;
|
||||
matrix.m21 = matrix.m11 * animationFrameFrom;
|
||||
|
||||
SpriteLevelMixer.setMatrix3f(matrix);
|
||||
SpriteLevelMixer.setBlendColor(factor, factor, factor, factor);
|
||||
SpriteLevelMixer.setBiasColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
SpriteLevelMixer.drawSprite(0);
|
||||
|
||||
matrix.m21 = matrix.m11 * animationFrameTo;
|
||||
SpriteLevelMixer.setMatrix3f(matrix);
|
||||
float fac1 = 1.0f - factor;
|
||||
SpriteLevelMixer.setBlendColor(fac1, fac1, fac1, fac1);
|
||||
|
||||
SpriteLevelMixer.drawSprite(0);
|
||||
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.disableBlend();
|
||||
|
||||
GlStateManager.bindTexture(storeTexture);
|
||||
GlStateManager.viewport(storeViewport[0], storeViewport[1], storeViewport[2], storeViewport[3]);
|
||||
GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
_wglReadBuffer(_GL_COLOR_ATTACHMENT0);
|
||||
_wglCopyTexSubImage2D(GL_TEXTURE_2D, level, dx, dy, 0, 0, w, h);
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
public int getFrameCount() {
|
||||
return frameCount;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user