    001package net.minecraft.client.renderer.texture;
    002
    003import cpw.mods.fml.client.TextureFXManager;
    004import cpw.mods.fml.relauncher.Side;
    005import cpw.mods.fml.relauncher.SideOnly;
    006
    007import java.awt.image.BufferedImage;
    008import java.io.BufferedReader;
    009import java.util.ArrayList;
    010import java.util.List;
    011
    012import net.minecraft.client.texturepacks.ITexturePack;
    013import net.minecraft.util.Icon;
    014import net.minecraft.util.Tuple;
    015
    016@SideOnly(Side.CLIENT)
    017public class TextureStitched implements Icon
    018{
    019    private final String textureName;
    020
    021    /** texture sheet containing this texture */
    022    protected Texture textureSheet;
    023    protected List textureList;
    024    private List listAnimationTuples;
    025    protected boolean rotated;
    026
    027    /** x position of this icon on the texture sheet in pixels */
    028    protected int originX;
    029
    030    /** y position of this icon on the texture sheet in pixels */
    031    protected int originY;
    032
    033    /** width of this icon in pixels */
    034    private int width;
    035
    036    /** height of this icon in pixels */
    037    private int height;
    038    private float minU;
    039    private float maxU;
    040    private float minV;
    041    private float maxV;
    042    private float widthNorm;
    043    private float heightNorm;
    044    protected int frameCounter = 0;
    045    protected int tickCounter = 0;
    046
    047    public static TextureStitched makeTextureStitched(String par0Str)
    048    {
    049        return (TextureStitched)("clock".equals(par0Str) ? new TextureClock() : ("compass".equals(par0Str) ? new TextureCompass() : new TextureStitched(par0Str)));
    050    }
    051
    052    protected TextureStitched(String par1)
    053    {
    054        this.textureName = par1;
    055    }
    056
    057    public void init(Texture par1Texture, List par2List, int par3, int par4, int par5, int par6, boolean par7)
    058    {
    059        this.textureSheet = par1Texture;
    060        this.textureList = par2List;
    061        this.originX = par3;
    062        this.originY = par4;
    063        this.width = par5;
    064        this.height = par6;
    065        this.rotated = par7;
    066        float f = 0.01F / (float)par1Texture.getWidth();
    067        float f1 = 0.01F / (float)par1Texture.getHeight();
    068        this.minU = (float)par3 / (float)par1Texture.getWidth() + f;
    069        this.maxU = (float)(par3 + par5) / (float)par1Texture.getWidth() - f;
    070        this.minV = (float)par4 / (float)par1Texture.getHeight() + f1;
    071        this.maxV = (float)(par4 + par6) / (float)par1Texture.getHeight() - f1;
    072        this.widthNorm = (float)par5 / 16.0F;
    073        this.heightNorm = (float)par6 / 16.0F;
    074        TextureFXManager.instance().getHelper().doTextureUpload(this);
    075        if (this.rotated)
    076        {
    077            TextureFXManager.instance().getHelper().rotateTexture(this.textureSheet, this.textureSheet.getTextureData());
    078        }
    079    }
    080
    081    public void copyFrom(TextureStitched par1TextureStitched)
    082    {
    083        this.init(par1TextureStitched.textureSheet, par1TextureStitched.textureList, par1TextureStitched.originX, par1TextureStitched.originY, par1TextureStitched.width, par1TextureStitched.height, par1TextureStitched.rotated);
    084    }
    085
    086    /**
    087     * Returns the X position of this icon on its texture sheet, in pixels.
    088     */
    089    public int getOriginX()
    090    {
    091        return this.originX;
    092    }
    093
    094    /**
    095     * Returns the Y position of this icon on its texture sheet, in pixels.
    096     */
    097    public int getOriginY()
    098    {
    099        return this.originY;
    100    }
    101
    102    /**
    103     * Returns the minimum U coordinate to use when rendering with this icon.
    104     */
    105    public float getMinU()
    106    {
    107        return this.minU;
    108    }
    109
    110    /**
    111     * Returns the maximum U coordinate to use when rendering with this icon.
    112     */
    113    public float getMaxU()
    114    {
    115        return this.maxU;
    116    }
    117
    118    /**
    119     * Gets a U coordinate on the icon. 0 returns uMin and 16 returns uMax. Other arguments return in-between values.
    120     */
    121    public float getInterpolatedU(double par1)
    122    {
    123        float f = this.maxU - this.minU;
    124        return this.minU + f * ((float)par1 / 16.0F);
    125    }
    126
    127    /**
    128     * Returns the minimum V coordinate to use when rendering with this icon.
    129     */
    130    public float getMinV()
    131    {
    132        return this.minV;
    133    }
    134
    135    /**
    136     * Returns the maximum V coordinate to use when rendering with this icon.
    137     */
    138    public float getMaxV()
    139    {
    140        return this.maxV;
    141    }
    142
    143    /**
    144     * Gets a V coordinate on the icon. 0 returns vMin and 16 returns vMax. Other arguments return in-between values.
    145     */
    146    public float getInterpolatedV(double par1)
    147    {
    148        float f = this.maxV - this.minV;
    149        return this.minV + f * ((float)par1 / 16.0F);
    150    }
    151
    152    public String getIconName()
    153    {
    154        return this.textureName;
    155    }
    156
    157    /**
    158     * Returns the width of the texture sheet this icon is on, in pixels.
    159     */
    160    public int getSheetWidth()
    161    {
    162        return this.textureSheet.getWidth();
    163    }
    164
    165    /**
    166     * Returns the height of the texture sheet this icon is on, in pixels.
    167     */
    168    public int getSheetHeight()
    169    {
    170        return this.textureSheet.getHeight();
    171    }
    172
    173    public void updateAnimation()
    174    {
    175        if (this.listAnimationTuples != null)
    176        {
    177            Tuple tuple = (Tuple)this.listAnimationTuples.get(this.frameCounter);
    178            ++this.tickCounter;
    179
    180            if (this.tickCounter >= ((Integer)tuple.getSecond()).intValue())
    181            {
    182                int i = ((Integer)tuple.getFirst()).intValue();
    183                this.frameCounter = (this.frameCounter + 1) % this.listAnimationTuples.size();
    184                this.tickCounter = 0;
    185                tuple = (Tuple)this.listAnimationTuples.get(this.frameCounter);
    186                int j = ((Integer)tuple.getFirst()).intValue();
    187
    188                if (i != j && j >= 0 && j < this.textureList.size())
    189                {
    190                    this.textureSheet.copyFrom(this.originX, this.originY, (Texture)this.textureList.get(j), false); //FML: We rotate the textures in init.
    191                }
    192            }
    193        }
    194        else
    195        {
    196            int k = this.frameCounter;
    197            this.frameCounter = (this.frameCounter + 1) % this.textureList.size();
    198
    199            if (k != this.frameCounter)
    200            {
    201                this.textureSheet.copyFrom(this.originX, this.originY, (Texture)this.textureList.get(this.frameCounter), false); //FML: We rotate the textures in init.
    202            }
    203        }
    204    }
    205
    206    public void readAnimationInfo(BufferedReader par1BufferedReader)
    207    {
    208        ArrayList arraylist = new ArrayList();
    209
    210        try
    211        {
    212            for (String s = par1BufferedReader.readLine(); s != null; s = par1BufferedReader.readLine())
    213            {
    214                s = s.trim();
    215
    216                if (s.length() > 0)
    217                {
    218                    String[] astring = s.split(",");
    219                    String[] astring1 = astring;
    220                    int i = astring.length;
    221
    222                    for (int j = 0; j < i; ++j)
    223                    {
    224                        String s1 = astring1[j];
    225                        int k = s1.indexOf(42);
    226
    227                        if (k > 0)
    228                        {
    229                            Integer integer = new Integer(s1.substring(0, k));
    230                            Integer integer1 = new Integer(s1.substring(k + 1));
    231                            arraylist.add(new Tuple(integer, integer1));
    232                        }
    233                        else
    234                        {
    235                            arraylist.add(new Tuple(new Integer(s1), Integer.valueOf(1)));
    236                        }
    237                    }
    238                }
    239            }
    240        }
    241        catch (Exception exception)
    242        {
    243            System.err.println("Failed to read animation info for " + this.textureName + ": " + exception.getMessage());
    244        }
    245
    246        if (!arraylist.isEmpty() && arraylist.size() < 600)
    247        {
    248            this.listAnimationTuples = arraylist;
    249        }
    250    }
    251
    252    public void createAndUploadTextures()
    253    {
    254        for (Texture t : ((List<Texture>)textureList))
    255        {
    256            t.createAndUploadTexture();
    257        }
    258    }
    259
    260    //===================================================================================================
    261    //                                           Forge Start
    262    //===================================================================================================
    263    /**
    264     * Called when texture packs are refreshed, from TextureManager.createNewTexture,
    265     * allows for finer control over loading the animation lists and verification of the image.
    266     * If the return value from this is true, no further loading will be done by vanilla code.
    267     *
    268     * You need to add all Texture's to the textures argument. At the end of this function at least one
    269     * entry should be in that argument, or a error should of been thrown.
    270     *
    271     * @param manager The invoking manager
    272     * @param texturepack Current texture pack
    273     * @param name The name of the texture
    274     * @param fileName Resource path for this texture
    275     * @param image Buffered image of the loaded resource
    276     * @param textures ArrayList of element type Texture, split textures should be added to this list for the stitcher to handle.
    277     * @return Return true to skip further vanilla texture loading for this texture
    278     */
    279    public boolean loadTexture(TextureManager manager, ITexturePack texturepack, String name, String fileName, BufferedImage image, ArrayList textures)
    280    {
    281        return false;
    282    }
    283}