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}