Package com.pclewis.mcpatcher.mod

Source Code of com.pclewis.mcpatcher.mod.TextureUtils

package com.pclewis.mcpatcher.mod;

import com.pclewis.mcpatcher.MCLogger;
import com.pclewis.mcpatcher.MCPatcherUtils;
import com.pclewis.mcpatcher.TexturePackAPI;
import net.minecraft.client.Minecraft;
import net.minecraft.src.*;
import org.lwjgl.opengl.PixelFormat;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class TextureUtils {
    private static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.HD_TEXTURES);

    private static final boolean animatedFire = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "animatedFire", true);
    private static final boolean animatedLava = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "animatedLava", true);
    private static final boolean animatedWater = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "animatedWater", true);
    private static final boolean animatedPortal = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "animatedPortal", true);
    private static final boolean customFire = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "customFire", true);
    private static final boolean customLava = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "customLava", true);
    private static final boolean customWater = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "customWater", true);
    private static final boolean customPortal = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "customPortal", true);
    private static final boolean customOther = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "customOther", true);
    private static final boolean fancyCompass = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "fancyCompass", true);

    private static final boolean useTextureCache = false;
    private static final boolean reclaimGLMemory = false;
    private static final boolean useZombieHack = MCPatcherUtils.getBoolean(MCPatcherUtils.HD_TEXTURES, "zombieHack", true);
    private static final int zombieAspectRatio = getAspectRatio("/mob/zombie.png");
    private static final int pigZombieAspectRatio = getAspectRatio("/mob/pigzombie.png");

    private static final int aaSamples = MCPatcherUtils.getInt(MCPatcherUtils.HD_TEXTURES, "antiAliasing", 0);

    private static final int LAVA_STILL_TEXTURE_INDEX = 14 * 16 + 13// Block.lavaStill.blockIndexInTexture
    private static final int LAVA_FLOWING_TEXTURE_INDEX = LAVA_STILL_TEXTURE_INDEX + 1; // Block.lavaMoving.blockIndexInTexture
    private static final int WATER_STILL_TEXTURE_INDEX = 12 * 16 + 13; // Block.waterStill.blockIndexInTexture
    private static final int WATER_FLOWING_TEXTURE_INDEX = WATER_STILL_TEXTURE_INDEX + 1; // Block.waterMoving.blockIndexInTexture
    private static final int FIRE_E_W_TEXTURE_INDEX = 1 * 16 + 15; // Block.fire.blockIndexInTexture;
    private static final int FIRE_N_S_TEXTURE_INDEX = FIRE_E_W_TEXTURE_INDEX + 16;
    private static final int PORTAL_TEXTURE_INDEX = 0 * 16 + 14; // Block.portal.blockIndexInTexture

    private static final String ALL_ITEMS = "/gui/allitems.png";
    private static final String ALL_ITEMSX = "/gui/allitemsx.png";

    private static boolean enableResizing = true;
    private static final HashMap<String, Integer> expectedColumns = new HashMap<String, Integer>();

    private static final HashMap<String, BufferedImage> imageCache = new HashMap<String, BufferedImage>();

    private static boolean bindImageReentry;

    public static boolean oldCreativeGui;

    static {
        expectedColumns.put("/terrain.png", 16);
        expectedColumns.put("/gui/items.png", 16);
        expectedColumns.put("/misc/dial.png", 1);

        logger.fine("/mob/zombie.png aspect ratio is %d:1", zombieAspectRatio);
        logger.fine("/mob/pigzombie.png aspect ratio is %d:1", pigZombieAspectRatio);

        TexturePackAPI.instance = new TexturePackAPI() {
            @Override
            protected InputStream getInputStreamImpl(String s) {
                InputStream input;
                if (oldCreativeGui && s.equals(ALL_ITEMS)) {
                    input = super.getInputStreamImpl(ALL_ITEMSX);
                    if (input != null) {
                        return input;
                    }
                }
                input = super.getInputStreamImpl(s);
                if (input == null && s.startsWith("/anim/custom_")) {
                    input = super.getInputStreamImpl(s.substring(5));
                }
                return input;
            }

            @Override
            protected BufferedImage getImageImpl(String s) {
                BufferedImage image;
                if (useTextureCache && enableResizing) {
                    image = imageCache.get(s);
                    if (image != null) {
                        return image;
                    }
                }

                image = super.getImageImpl(s);
                if (image == null) {
                    return null;
                }
                int width = image.getWidth();
                int height = image.getHeight();
                logger.finer("opened %s %dx%d", s, width, height);

                if (enableResizing) {
                    Integer i = expectedColumns.get(s);
                    if (i != null && width != i * TileSize.int_size) {
                        image = resizeImage(image, i * TileSize.int_size);
                    }
                }

                if (s.matches("^/mob/.*_eyes\\d*\\.png$")) {
                    int p = 0;
                    for (int x = 0; x < width; x++) {
                        for (int y = 0; y < height; y++) {
                            int argb = image.getRGB(x, y);
                            if ((argb & 0xff000000) == 0 && argb != 0) {
                                image.setRGB(x, y, 0);
                                p++;
                            }
                        }
                    }
                    if (p > 0) {
                        logger.finest("  fixed %d transparent pixels", p, s);
                    }
                }

                image = resizeMobTexture("zombie", zombieAspectRatio, s, image);
                image = resizeMobTexture("pigzombie", pigZombieAspectRatio, s, image);

                if (useTextureCache && enableResizing) {
                    imageCache.put(s, image);
                }
                return image;
            }

            private BufferedImage resizeMobTexture(String mob, int aspectRatio, String texture, BufferedImage image) {
                if (aspectRatio != 0 && texture.matches("/mob/" + mob + "\\d*\\.png")) {
                    int width = image.getWidth();
                    int height = image.getHeight();
                    if (aspectRatio == 1 && width == 2 * height) {
                        logger.fine("resizing %s to %dx%d", texture, width, 2 * height);
                        BufferedImage newImage = new BufferedImage(width, 2 * height, BufferedImage.TYPE_INT_ARGB);
                        Graphics2D graphics2D = newImage.createGraphics();
                        graphics2D.drawImage(image, 0, 0, width, height, 0, 0, width, height, null);
                        image = newImage;
                    } else if (aspectRatio == 2 && width == height) {
                        logger.fine("resizing %s to %dx%d", texture, width, height / 2);
                        BufferedImage newImage = new BufferedImage(width, height / 2, BufferedImage.TYPE_INT_ARGB);
                        Graphics2D graphics2D = newImage.createGraphics();
                        graphics2D.drawImage(image, 0, 0, width, height / 2, 0, 0, width, height / 2, null);
                        image = newImage;
                    }
                }
                return image;
            }
        };

        TexturePackAPI.ChangeHandler.register(new TexturePackAPI.ChangeHandler(MCPatcherUtils.HD_TEXTURES, 1) {
            @Override
            protected void onChange() {
                imageCache.clear();
                MipmapHelper.reset();
                setTileSize();
                Minecraft minecraft = MCPatcherUtils.getMinecraft();
                minecraft.renderEngine.reloadTextures(minecraft);
                if (ColorizerWater.colorBuffer != ColorizerFoliage.colorBuffer) {
                    refreshColorizer(ColorizerWater.colorBuffer, "/misc/watercolor.png");
                }
                refreshColorizer(ColorizerGrass.colorBuffer, "/misc/grasscolor.png");
                refreshColorizer(ColorizerFoliage.colorBuffer, "/misc/foliagecolor.png");
            }
        });
    }

    private static int getAspectRatio(String texture) {
        int ratio = 0;
        if (useZombieHack) {
            BufferedImage image = MCPatcherUtils.readImage(TextureUtils.class.getResourceAsStream(texture));
            if (image != null) {
                int width = image.getWidth();
                int height = image.getHeight();
                if (width == 2 * height) {
                    ratio = 2;
                } else if (width == height) {
                    ratio = 1;
                }
            }
        }
        return ratio;
    }

    public static void registerTextureFX(java.util.List<TextureFX> textureList, TextureFX textureFX) {
        TextureFX fx = refreshTextureFX(textureFX);
        if (fx != null) {
            logger.finer("registering new TextureFX class %s", textureFX.getClass().getName());
            textureList.add(fx);
            fx.onTick();
        }
    }

    private static TextureFX refreshTextureFX(TextureFX textureFX) {
        if (textureFX instanceof Compass ||
            textureFX instanceof Watch ||
            textureFX instanceof StillLava ||
            textureFX instanceof FlowLava ||
            textureFX instanceof StillWater ||
            textureFX instanceof FlowWater ||
            textureFX instanceof Fire ||
            textureFX instanceof Portal) {
            return null;
        }
        Class<? extends TextureFX> textureFXClass = textureFX.getClass();
        logger.info("attempting to refresh unknown animation %s", textureFXClass.getName());
        Minecraft minecraft = MCPatcherUtils.getMinecraft();
        loop:
        for (int i = 0; i < 3; i++) {
            Constructor<? extends TextureFX> constructor;
            try {
                switch (i) {
                    case 0:
                        constructor = textureFXClass.getConstructor(Minecraft.class, Integer.TYPE);
                        textureFX = constructor.newInstance(minecraft, TileSize.int_size);
                        break loop;

                    case 1:
                        constructor = textureFXClass.getConstructor(Minecraft.class);
                        textureFX = constructor.newInstance(minecraft);
                        break loop;

                    case 2:
                        constructor = textureFXClass.getConstructor();
                        textureFX = constructor.newInstance();
                        break loop;

                    default:
                        break;
                }
            } catch (NoSuchMethodException e) {
            } catch (IllegalAccessException e) {
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (textureFX.imageData.length < TileSize.int_numBytes) {
            logger.finer("resizing %s buffer from %d to %d bytes",
                textureFXClass.getName(), textureFX.imageData.length, TileSize.int_numBytes
            );
            textureFX.imageData = new byte[TileSize.int_numBytes];
        }
        try {
            Method setup = textureFXClass.getDeclaredMethod("setup");
            setup.setAccessible(true);
            logger.info("calling %s", setup);
            setup.invoke(textureFX);
        } catch (NoSuchMethodException e) {
        } catch (Exception e) {
            e.printStackTrace();
        }
        return textureFX;
    }

    public static void refreshTextureFX(java.util.List<TextureFX> textureList) {
        ArrayList<TextureFX> savedTextureFX = new ArrayList<TextureFX>();
        for (TextureFX t : textureList) {
            TextureFX fx = refreshTextureFX(t);
            if (fx != null) {
                savedTextureFX.add(fx);
            }
        }
        textureList.clear();
        CustomAnimation.clear();

        Minecraft minecraft = MCPatcherUtils.getMinecraft();
        Compass compass = new Compass(minecraft);
        textureList.add(compass);
        if (fancyCompass && FancyCompass.refresh()) {
            compass.tileSize = 0;
        }
        textureList.add(new Watch(minecraft));

        boolean isDefault = TexturePackAPI.isDefaultTexturePack();

        if (!isDefault && customLava) {
            CustomAnimation.addStripOrTile("/terrain.png", "lava_still", LAVA_STILL_TEXTURE_INDEX, 1, -1, -1);
            CustomAnimation.addStripOrTile("/terrain.png", "lava_flowing", LAVA_FLOWING_TEXTURE_INDEX, 2, 3, 6);
        } else if (animatedLava) {
            textureList.add(new StillLava());
            textureList.add(new FlowLava());
        }

        if (!isDefault && customWater) {
            CustomAnimation.addStripOrTile("/terrain.png", "water_still", WATER_STILL_TEXTURE_INDEX, 1, -1, -1);
            CustomAnimation.addStripOrTile("/terrain.png", "water_flowing", WATER_FLOWING_TEXTURE_INDEX, 2, 0, 0);
        } else if (animatedWater) {
            textureList.add(new StillWater());
            textureList.add(new FlowWater());
        }

        if (!isDefault && customFire && TexturePackAPI.hasResource("/anim/custom_fire_e_w.png") && TexturePackAPI.hasResource("/anim/custom_fire_n_s.png")) {
            CustomAnimation.addStrip("/terrain.png", "fire_n_s", FIRE_N_S_TEXTURE_INDEX, 1);
            CustomAnimation.addStrip("/terrain.png", "fire_e_w", FIRE_E_W_TEXTURE_INDEX, 1);
        } else if (animatedFire) {
            textureList.add(new Fire(0));
            textureList.add(new Fire(1));
        }

        if (!isDefault && customPortal && TexturePackAPI.hasResource("/anim/custom_portal.png")) {
            CustomAnimation.addStrip("/terrain.png", "portal", PORTAL_TEXTURE_INDEX, 1);
        } else if (animatedPortal) {
            textureList.add(new Portal());
        }

        if (customOther) {
            addOtherTextureFX("/terrain.png", "terrain");
            addOtherTextureFX("/gui/items.png", "item");
            for (String name : TexturePackAPI.listResources("/anim/", ".properties")) {
                if (!isCustomTerrainItemResource(name)) {
                    CustomAnimation.addStrip(TexturePackAPI.getProperties(name));
                }
            }
        }

        for (TextureFX t : savedTextureFX) {
            textureList.add(t);
        }

        for (TextureFX t : textureList) {
            t.onTick();
        }

        CustomAnimation.updateAll();
    }

    private static void addOtherTextureFX(String textureName, String imageName) {
        for (int tileNum = 0; tileNum < 256; tileNum++) {
            String resource = "/anim/custom_" + imageName + "_" + tileNum + ".png";
            if (TexturePackAPI.hasResource(resource)) {
                CustomAnimation.addStrip(textureName, imageName + "_" + tileNum, tileNum, 1);
            }
        }
    }

    public static ByteBuffer getByteBuffer(ByteBuffer buffer, byte[] data) {
        buffer.clear();
        final int have = buffer.capacity();
        final int needed = data.length;
        if (needed > have || (reclaimGLMemory && have >= 4 * needed)) {
            logger.finest("resizing gl buffer from 0x%x to 0x%x", have, needed);
            buffer = GLAllocation.createDirectByteBuffer(needed);
        }
        buffer.put(data);
        buffer.position(0).limit(needed);
        TileSize.int_glBufferSize = needed;
        return buffer;
    }

    private static boolean isCustomTerrainItemResource(String resource) {
        resource = resource.replaceFirst("^/anim", "").replaceFirst("\\.(png|properties)$", "");
        return resource.equals("/custom_lava_still") ||
            resource.equals("/custom_lava_flowing") ||
            resource.equals("/custom_water_still") ||
            resource.equals("/custom_water_flowing") ||
            resource.equals("/custom_fire_n_s") ||
            resource.equals("/custom_fire_e_w") ||
            resource.equals("/custom_portal") ||
            resource.matches("^/custom_(terrain|item)_\\d+$");
    }

    public static BufferedImage getImage(Object o1, Object o2, String resource) throws IOException {
        return TexturePackAPI.getImage(resource);
    }

    private static boolean setTileSize() {
        int size = getTileSize();
        if (size == TileSize.int_size) {
            logger.fine("tile size %d unchanged", size);
            return false;
        } else {
            logger.fine("setting tile size to %d (was %d)", size, TileSize.int_size);
            TileSize.setTileSize(size);
            return true;
        }
    }

    private static int getTileSize() {
        int size = 0;
        enableResizing = false;
        for (Map.Entry<String, Integer> entry : expectedColumns.entrySet()) {
            BufferedImage image = TexturePackAPI.getImage(entry.getKey());
            if (image != null) {
                int newSize = image.getWidth() / entry.getValue();
                logger.fine("%s tile size is %d", entry.getKey(), newSize);
                size = Math.max(size, newSize);
            }
        }
        enableResizing = true;
        return size > 0 ? size : 16;
    }

    static BufferedImage resizeImage(BufferedImage image, int width) {
        if (width == image.getWidth()) {
            return image;
        }
        int height = image.getHeight() * width / image.getWidth();
        logger.finer("resizing to %dx%d", width, height);
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = newImage.createGraphics();
        graphics2D.drawImage(image, 0, 0, width, height, null);
        return newImage;
    }

    private static void refreshColorizer(int[] colorBuffer, String resource) {
        BufferedImage image = TexturePackAPI.getImage(resource);
        logger.fine("reloading %s", resource);
        if (image != null) {
            image.getRGB(0, 0, 256, 256, colorBuffer, 0, 256);
        }
    }

    public static boolean bindImageBegin() {
        if (bindImageReentry) {
            logger.warning("caught TextureFX.bindImage recursion");
            return false;
        }
        bindImageReentry = true;
        return true;
    }

    public static void bindImageEnd() {
        bindImageReentry = false;
    }

    public static PixelFormat getAAPixelFormat(PixelFormat format) {
        return aaSamples > 0 ? format.withSamples(aaSamples) : format;
    }
}
TOP

Related Classes of com.pclewis.mcpatcher.mod.TextureUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.