mirror of
https://git.eaglercraft.rip/eaglercraft/eaglercraft-b1.3.git
synced 2025-04-16 21:47:40 -07:00
156 lines
4.5 KiB
Java
156 lines
4.5 KiB
Java
package net.lax1dude.eaglercraft.beta;
|
|
|
|
import java.nio.IntBuffer;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
|
|
import net.lax1dude.eaglercraft.EaglerAdapter;
|
|
import net.lax1dude.eaglercraft.EaglerImage;
|
|
import net.minecraft.src.GLAllocation;
|
|
|
|
public class SpriteSheetTexture {
|
|
|
|
public final String name;
|
|
public final int iconIndex;
|
|
public final int iconTileSize;
|
|
private IntBuffer buffer = null;
|
|
private int dataFrameCount = 0;
|
|
private int[] frameSet = null;
|
|
public int ticks = 0;
|
|
|
|
private int[] mipmapOffsets = new int[5];
|
|
|
|
public SpriteSheetTexture(String name, int iconIndex, int iconTileSize) {
|
|
this.name = name;
|
|
this.iconIndex = iconIndex;
|
|
this.iconTileSize = iconTileSize;
|
|
reloadData();
|
|
}
|
|
|
|
public void update() {
|
|
ticks = (ticks + 1) % frameSet.length;
|
|
}
|
|
|
|
public IntBuffer grabFrame(int lvl) {
|
|
int offWidth = 16 >> lvl;
|
|
int step = offWidth * offWidth * iconTileSize * iconTileSize;
|
|
int startIndex = mipmapOffsets[lvl] + step * frameSet[ticks];
|
|
buffer.limit(startIndex + step);
|
|
buffer.position(startIndex);
|
|
return buffer;
|
|
}
|
|
|
|
public void reloadData() {
|
|
ticks = 0;
|
|
buffer = null;
|
|
frameSet = null;
|
|
|
|
byte[] imgBytes = EaglerAdapter.loadResourceBytes("/sprite_sheet/" + name + ".png");
|
|
if(imgBytes == null) {
|
|
return;
|
|
}
|
|
|
|
int dim = iconTileSize * iconTileSize * 256;
|
|
EaglerImage img = EaglerImage.loadImage(imgBytes);
|
|
dataFrameCount = img.data.length / dim;
|
|
|
|
ArrayList<Integer> loadedFrameSet = new ArrayList();
|
|
byte[] metaBytes = EaglerAdapter.loadResourceBytes("/sprite_sheet/" + name + ".txt");
|
|
|
|
if(metaBytes == null) {
|
|
for(int i = 0; i < dataFrameCount; ++i) {
|
|
loadedFrameSet.add(i);
|
|
}
|
|
}else {
|
|
String str = new String(metaBytes, StandardCharsets.UTF_8);
|
|
String[] splitted = str.split("\\s*,\\s*");
|
|
for(int i = 0; i < splitted.length; ++i) {
|
|
String idxStr = splitted[i];
|
|
int z = idxStr.indexOf('*');
|
|
if(z != -1) {
|
|
int idx = Integer.parseInt(idxStr.substring(0, z));
|
|
int c = Integer.parseInt(idxStr.substring(z + 1));
|
|
for(int j = 0; j < c; ++j) {
|
|
loadedFrameSet.add(idx);
|
|
}
|
|
}else {
|
|
loadedFrameSet.add(Integer.parseInt(idxStr));
|
|
}
|
|
}
|
|
}
|
|
|
|
frameSet = new int[loadedFrameSet.size()];
|
|
for(int i = 0; i < frameSet.length; ++i) {
|
|
frameSet[i] = loadedFrameSet.get(i).intValue();
|
|
}
|
|
|
|
buffer = GLAllocation.createDirectIntBuffer(
|
|
16 * 16 * dataFrameCount * iconTileSize * iconTileSize +
|
|
8 * 8 * dataFrameCount * iconTileSize * iconTileSize +
|
|
4 * 4 * dataFrameCount * iconTileSize * iconTileSize +
|
|
2 * 2 * dataFrameCount * iconTileSize * iconTileSize +
|
|
dataFrameCount * iconTileSize * iconTileSize
|
|
);
|
|
|
|
int[] texData = swapRB(img.data);
|
|
mipmapOffsets[0] = 0;
|
|
buffer.put(texData);
|
|
mipmapOffsets[1] = buffer.position();
|
|
texData = downscale(texData, 16 * iconTileSize, 16 * iconTileSize * dataFrameCount);
|
|
buffer.put(texData);
|
|
mipmapOffsets[2] = buffer.position();
|
|
texData = downscale(texData, 8 * iconTileSize, 8 * iconTileSize * dataFrameCount);
|
|
buffer.put(texData);
|
|
mipmapOffsets[3] = buffer.position();
|
|
texData = downscale(texData, 4 * iconTileSize, 4 * iconTileSize * dataFrameCount);
|
|
buffer.put(texData);
|
|
mipmapOffsets[4] = buffer.position();
|
|
texData = downscale(texData, 2 * iconTileSize, 2 * iconTileSize * dataFrameCount);
|
|
buffer.put(texData);
|
|
|
|
}
|
|
|
|
private static int[] downscale(int[] in, int sw, int sh) {
|
|
int dw = sw / 2;
|
|
int dh = sh / 2;
|
|
int[] ret = new int[dw * dh];
|
|
for(int y = 0; y < dh; ++y) {
|
|
for(int x = 0; x < dw; ++x) {
|
|
int a = in[((x * 2) + (y * 2) * sw)];
|
|
int b = in[((x * 2 + 1) + (y * 2) * sw)];
|
|
int c = in[((x * 2 + 1) + (y * 2 + 1) * sw)];
|
|
int d = in[((x * 2) + (y * 2 + 1) * sw)];
|
|
int b1= (((a >> 26) & 0x3F)) +
|
|
(((b >> 26) & 0x3F)) +
|
|
(((c >> 26) & 0x3F)) +
|
|
(((d >> 26) & 0x3F));
|
|
int b2= (((a >> 18) & 0x3F)) +
|
|
(((b >> 18) & 0x3F)) +
|
|
(((c >> 18) & 0x3F)) +
|
|
(((d >> 18) & 0x3F));
|
|
int b3= (((a >> 10) & 0x3F)) +
|
|
(((b >> 10) & 0x3F)) +
|
|
(((c >> 10) & 0x3F)) +
|
|
(((d >> 10) & 0x3F));
|
|
int b4= (((a >> 2) & 0x3F)) +
|
|
(((b >> 2) & 0x3F)) +
|
|
(((c >> 2) & 0x3F)) +
|
|
(((d >> 2) & 0x3F));
|
|
ret[y * dw + x] = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
private static int[] swapRB(int[] in) {
|
|
int[] out = new int[in.length];
|
|
for(int i = 0; i < in.length; ++i) {
|
|
int r = (in[i] >> 16) & 0xFF;
|
|
int b = in[i] & 0xFF;
|
|
out[i] = (in[i] & 0xFF00FF00) | (b << 16) | r;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
}
|