Files
MCCustomSkinLoader/Common/source/customskinloader/fake/FakeSkinBuffer.java
T

151 lines
6.4 KiB
Java
Raw Normal View History

2016-12-25 17:05:30 +08:00
package customskinloader.fake;
2016-08-28 19:08:59 +08:00
2018-07-25 15:55:03 +08:00
import customskinloader.CustomSkinLoader;
import customskinloader.fake.texture.FakeBufferedImage;
import customskinloader.fake.texture.FakeImage;
2018-07-25 21:06:16 +08:00
import customskinloader.fake.texture.FakeNativeImage;
2018-07-25 15:55:03 +08:00
2016-08-28 19:08:59 +08:00
import java.awt.image.BufferedImage;
2016-12-25 17:05:30 +08:00
public class FakeSkinBuffer implements net.minecraft.client.renderer.IImageBuffer {
2016-08-28 19:08:59 +08:00
2018-07-25 15:55:03 +08:00
private int ratio = 1;
private FakeImage image = null;
2018-05-18 21:06:28 +08:00
2018-07-25 21:06:16 +08:00
//parseUserSkin for 1.13+
public net.minecraft.client.renderer.texture.NativeImage func_195786_a(net.minecraft.client.renderer.texture.NativeImage image) {
if (image == null)
return null;
FakeImage img = parseUserSkin(new FakeNativeImage(image));
if (img instanceof FakeNativeImage)
return ((FakeNativeImage) img).getImage();
CustomSkinLoader.logger.warning("Failed to parseUserSkin(func_195786_a).");
return null;
}
//parseUserSkin for 1.12.2-
2018-02-12 12:20:28 +08:00
public BufferedImage parseUserSkin(BufferedImage image) {
2018-07-25 15:55:03 +08:00
if (image == null)
2018-02-12 12:20:28 +08:00
return null;
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
FakeImage img = parseUserSkin(new FakeBufferedImage(image));
if (img instanceof FakeBufferedImage)
return ((FakeBufferedImage) img).getImage();
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
CustomSkinLoader.logger.warning("Failed to parseUserSkin.");
return null;
}
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
public FakeImage parseUserSkin(FakeImage image) {
if (image == null) return null;
this.ratio = image.getWidth() / 64;
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
if (image.getHeight() != image.getWidth()) {//Single Layer
//Create a new image and copy origin image data
FakeImage img = image.createImage(64 * ratio, 64 * ratio);
img.copyImageData(image); image.close(); image = img;
image.fillArea(0 * ratio, 32 * ratio, 64 * ratio, 32 * ratio);
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
//Right Leg -> Left Leg
2018-07-26 20:50:41 +08:00
image.copyArea( 4 * ratio, 16 * ratio, 16 * ratio, 32 * ratio, 4 * ratio, 4 * ratio, true, false);//Top
image.copyArea( 8 * ratio, 16 * ratio, 16 * ratio, 32 * ratio, 4 * ratio, 4 * ratio, true, false);//Bottom
2018-07-25 15:55:03 +08:00
image.copyArea( 0 * ratio, 20 * ratio, 24 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Right
image.copyArea( 4 * ratio, 20 * ratio, 16 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Front
image.copyArea( 8 * ratio, 20 * ratio, 8 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Left
image.copyArea(12 * ratio, 20 * ratio, 16 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Back
//Right Arm -> Left Arm
2018-07-26 20:50:41 +08:00
image.copyArea(44 * ratio, 16 * ratio, -8 * ratio, 32 * ratio, 4 * ratio, 4 * ratio, true, false);//Top
image.copyArea(48 * ratio, 16 * ratio, -8 * ratio, 32 * ratio, 4 * ratio, 4 * ratio, true, false);//Bottom
2018-07-25 15:55:03 +08:00
image.copyArea(40 * ratio, 20 * ratio, 0 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Right
image.copyArea(44 * ratio, 20 * ratio, -8 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Front
image.copyArea(48 * ratio, 20 * ratio,-16 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Left
image.copyArea(52 * ratio, 20 * ratio, -8 * ratio, 32 * ratio, 4 * ratio, 12 * ratio, true, false);//Back
}
this.image = image;
setAreaDueToConfig( 0 * ratio, 0 * ratio, 32 * ratio, 16 * ratio);//Head - 1
setAreaTransparent(32 * ratio, 0 * ratio, 64 * ratio, 16 * ratio);//Head - 2
setAreaDueToConfig(16 * ratio, 16 * ratio, 40 * ratio, 32 * ratio);//Body - 1
setAreaTransparent(16 * ratio, 32 * ratio, 40 * ratio, 48 * ratio);//Body - 2
setAreaDueToConfig(40 * ratio, 16 * ratio, 56 * ratio, 32 * ratio);//Right Arm - 1
setAreaTransparent(40 * ratio, 32 * ratio, 56 * ratio, 48 * ratio);//Right Arm - 2
setAreaDueToConfig( 0 * ratio, 16 * ratio, 16 * ratio, 32 * ratio);//Right Leg - 1
setAreaTransparent( 0 * ratio, 32 * ratio, 16 * ratio, 48 * ratio);//Right Leg - 2
setAreaDueToConfig(32 * ratio, 48 * ratio, 48 * ratio, 64 * ratio);//Left Arm - 1
setAreaTransparent(48 * ratio, 48 * ratio, 64 * ratio, 64 * ratio);//Left Arm - 2
setAreaDueToConfig(16 * ratio, 48 * ratio, 32 * ratio, 64 * ratio);//Left Leg - 1
setAreaTransparent( 0 * ratio, 48 * ratio, 16 * ratio, 64 * ratio);//Left Leg - 2
return image;
2018-02-12 12:20:28 +08:00
}
2018-05-18 21:06:28 +08:00
/**
* Judge the type of skin
* Must be called after parseUserSkin
2018-07-25 15:55:03 +08:00
*
2018-05-18 21:06:28 +08:00
* @return type of skin (slim / default)
* @since 14.9
*/
2018-07-25 15:55:03 +08:00
public String judgeType() {
if (this.image == null)
2018-05-18 21:06:28 +08:00
return null;
2018-07-25 15:55:03 +08:00
if (((image.getRGBA(55, 20) & B) >>> 24) == 0)//if (55,20) is transparent
2018-05-18 21:06:28 +08:00
return "slim";
return "default";
}
/* 2^24-1
2018-02-12 12:20:28 +08:00
* 00000000 11111111 11111111 11111111 */
2018-07-25 15:55:03 +08:00
private static final int A = 16777215;
private static final int WHITE = getARGB(255, 255, 255, 255);
private static final int BLACK = getARGB(255, 0, 0, 0);
private boolean isFilled(int x0, int y0, int x1, int y1) {
int data = image.getRGBA(x0, y0);
if (data != WHITE && data != BLACK)
2018-02-12 12:20:28 +08:00
return false;
2018-07-25 15:55:03 +08:00
for (int x = x0; x < x1; ++x)
for (int y = y0; y < y1; ++y)
if (image.getRGBA(x, y) != data)
2018-02-12 12:20:28 +08:00
return false;
return true;
}
2018-07-25 15:55:03 +08:00
private void setAreaTransparent(int x0, int y0, int x1, int y1) {
if (!isFilled(x0, y0, x1, y1))
2018-02-12 12:20:28 +08:00
return;
2018-07-25 15:55:03 +08:00
for (int x = x0; x < x1; ++x)
for (int y = y0; y < y1; ++y)
image.setRGBA(x, y, image.getRGBA(x,y) & A);
2018-02-12 12:20:28 +08:00
}
2018-05-18 21:06:28 +08:00
2018-02-12 12:20:28 +08:00
/* -2^24
* 00000001 00000000 00000000 00000000 ->
* 11111110 11111111 11111111 11111111 ->
* 11111111 00000000 00000000 00000000 */
2018-07-25 15:55:03 +08:00
private static final int B = -16777216;
private void setAreaOpaque(int x0, int y0, int x1, int y1) {
for (int x = x0; x < x1; ++x)
for (int y = y0; y < y1; ++y)
image.setRGBA(x, y, image.getRGBA(x,y) | B);
2018-02-12 12:20:28 +08:00
}
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
private void setAreaDueToConfig(int x0, int y0, int x1, int y1) {
if (customskinloader.CustomSkinLoader.config.enableTransparentSkin)
setAreaTransparent(x0, y0, x1, y1);
2018-02-12 12:20:28 +08:00
else
2018-07-25 15:55:03 +08:00
setAreaOpaque(x0, y0, x1, y1);
2018-02-12 12:20:28 +08:00
}
2016-08-28 19:08:59 +08:00
2018-07-25 15:55:03 +08:00
public void skinAvailable() {
//A callback when skin loaded, nothing to do
2018-02-12 12:20:28 +08:00
}
2018-05-18 21:06:28 +08:00
2018-07-25 15:55:03 +08:00
private static int getARGB(int a, int r, int g, int b) {
2018-02-12 12:20:28 +08:00
return (a << 24) | (r << 16) | (g << 8) | b;
}
2016-08-28 19:08:59 +08:00
}