Package com.prupe.mcpatcher.hd

Source Code of com.prupe.mcpatcher.hd.CustomAnimation

package com.prupe.mcpatcher.hd;

import com.prupe.mcpatcher.Config;
import com.prupe.mcpatcher.MCLogger;
import com.prupe.mcpatcher.MCPatcherUtils;
import com.prupe.mcpatcher.TexturePackAPI;
import com.prupe.mcpatcher.TexturePackChangeHandler;
import com.prupe.mcpatcher.hd.CustomAnimation$1;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;
import net.minecraft.src.ResourceLocation;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class CustomAnimation implements Comparable<CustomAnimation> {
  private static final MCLogger logger = MCLogger.getLogger("Custom Animations", "Animation");
  private static final boolean enable = Config.getBoolean("Extended HD", "animations", true);
  private static final Map<ResourceLocation, Properties> pending = new HashMap();
  private static final List<CustomAnimation> animations = new ArrayList();
  private final ResourceLocation propertiesName;
  private final ResourceLocation dstName;
  private final ResourceLocation srcName;
  private final int mipmapLevel;
  private final ByteBuffer imageData;
  private final int x;
  private final int y;
  private final int w;
  private final int h;
  private int currentFrame;
  private int currentDelay;
  private int numFrames;
  private int[] tileOrder;
  private int[] tileDelay;
  private final int numTiles;
  private boolean error;

  public static void updateAll() {
    if (!pending.isEmpty()) {
      try {
        checkPendingAnimations();
      } catch (Throwable var2) {
        var2.printStackTrace();
        logger.error("%d remaining animations cleared", new Object[] {Integer.valueOf(pending.size())});
        pending.clear();
      }
    }

    Iterator i$ = animations.iterator();

    while (i$.hasNext()) {
      CustomAnimation animation = (CustomAnimation)i$.next();
      animation.update();
    }
  }

  private static void checkPendingAnimations() {
    ArrayList done = new ArrayList();
    Iterator i$ = pending.entrySet().iterator();

    while (i$.hasNext()) {
      Entry name = (Entry)i$.next();
      ResourceLocation name1 = (ResourceLocation)name.getKey();
      Properties properties = (Properties)name.getValue();
      ResourceLocation textureName = TexturePackAPI.parseResourceLocation(name1, MCPatcherUtils.getStringProperty(properties, "to", ""));

      if (TexturePackAPI.isTextureLoaded(textureName)) {
        addStrip(name1, properties);
        done.add(name1);
      }
    }

    if (!done.isEmpty()) {
      i$ = done.iterator();

      while (i$.hasNext()) {
        ResourceLocation name2 = (ResourceLocation)i$.next();
        pending.remove(name2);
      }

      Collections.sort(animations);
    }
  }

  private static void addStrip(ResourceLocation propertiesName, Properties properties) {
    ResourceLocation dstName = TexturePackAPI.parseResourceLocation(propertiesName, properties.getProperty("to", ""));

    if (dstName == null) {
      logger.error("%s: missing to= property", new Object[0]);
    } else {
      ResourceLocation srcName = TexturePackAPI.parseResourceLocation(propertiesName, properties.getProperty("from", ""));

      if (srcName == null) {
        logger.error("%s: missing from= property", new Object[0]);
      } else {
        BufferedImage srcImage = TexturePackAPI.getImage(srcName);

        if (srcImage == null) {
          logger.error("%s: image %s not found in texture pack", new Object[] {propertiesName, srcName});
        } else {
          int x = MCPatcherUtils.getIntProperty(properties, "x", 0);
          int y = MCPatcherUtils.getIntProperty(properties, "y", 0);
          int w = MCPatcherUtils.getIntProperty(properties, "w", 0);
          int h = MCPatcherUtils.getIntProperty(properties, "h", 0);

          if (dstName.toString().startsWith("minecraft:textures/atlas/")) {
            logger.error("%s: animations cannot have a target of %s", new Object[] {dstName});
          } else if (x >= 0 && y >= 0 && w > 0 && h > 0) {
            TexturePackAPI.bindTexture(dstName);
            int dstWidth = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_WIDTH);
            int dstHeight = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_HEIGHT);
            int levels = MipmapHelper.getMipmapLevelsForCurrentTexture();

            if (x + w <= dstWidth && y + h <= dstHeight) {
              int width = srcImage.getWidth();
              int height = srcImage.getHeight();

              if (width != w) {
                srcImage = resizeImage(srcImage, w);
                width = srcImage.getWidth();
                height = srcImage.getHeight();
              }

              if (width == w && height >= h) {
                ByteBuffer imageData = ByteBuffer.allocateDirect(4 * width * height);
                int[] argb = new int[width * height];
                byte[] rgba = new byte[4 * width * height];
                srcImage.getRGB(0, 0, width, height, argb, 0, width);
                ARGBtoRGBA(argb, rgba);
                imageData.put(rgba).flip();

                for (int mipmapLevel = 0; mipmapLevel <= levels; ++mipmapLevel) {
                  add(new CustomAnimation(propertiesName, srcName, dstName, mipmapLevel, x, y, w, h, imageData, height / h, properties));

                  if (((x | y | w | h) & 1) != 0 || w <= 0 || h <= 0) {
                    break;
                  }

                  ByteBuffer newImage = ByteBuffer.allocateDirect(width * height);
                  MipmapHelper.scaleHalf(imageData.asIntBuffer(), width, height, newImage.asIntBuffer(), 0);
                  imageData = newImage;
                  width >>= 1;
                  height >>= 1;
                  x >>= 1;
                  y >>= 1;
                  w >>= 1;
                  h >>= 1;
                }
              } else {
                logger.error("%s: %s dimensions %dx%d do not match %dx%d", new Object[] {propertiesName, srcName, Integer.valueOf(width), Integer.valueOf(height), Integer.valueOf(w), Integer.valueOf(h)});
              }
            } else {
              logger.error("%s: %s dimensions x=%d,y=%d,w=%d,h=%d exceed %s size %dx%d", new Object[] {propertiesName, srcName, Integer.valueOf(x), Integer.valueOf(y), Integer.valueOf(w), Integer.valueOf(h), dstName, Integer.valueOf(dstWidth), Integer.valueOf(dstHeight)});
            }
          } else {
            logger.error("%s: %s has invalid dimensions x=%d,y=%d,w=%d,h=%d", new Object[] {propertiesName, srcName, Integer.valueOf(x), Integer.valueOf(y), Integer.valueOf(w), Integer.valueOf(h)});
          }
        }
      }
    }
  }

  private static void add(CustomAnimation animation) {
    if (animation != null) {
      animations.add(animation);

      if (animation.mipmapLevel == 0) {
        logger.fine("new %s", new Object[] {animation});
      }
    }
  }

  private CustomAnimation(ResourceLocation propertiesName, ResourceLocation srcName, ResourceLocation dstName, int mipmapLevel, int x, int y, int w, int h, ByteBuffer imageData, int numFrames, Properties properties) {
    this.propertiesName = propertiesName;
    this.srcName = srcName;
    this.dstName = dstName;
    this.mipmapLevel = mipmapLevel;
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.imageData = imageData;
    this.numFrames = numFrames;
    this.currentFrame = -1;
    this.numTiles = numFrames;
    this.loadProperties(properties);
  }

  void update() {
    if (!this.error) {
      int texture = TexturePackAPI.getTextureIfLoaded(this.dstName);

      if (texture >= 0) {
        if (--this.currentDelay <= 0) {
          if (++this.currentFrame >= this.numFrames) {
            this.currentFrame = 0;
          }

          TexturePackAPI.bindTexture(texture);
          this.update(texture, 0, 0);
          int glError = GL11.glGetError();

          if (glError != 0) {
            logger.severe("%s: %s", new Object[] {this, GLU.gluErrorString(glError)});
            this.error = true;
          } else {
            this.currentDelay = this.getDelay();
          }
        }
      }
    }
  }

  public int compareTo(CustomAnimation o) {
    return this.dstName.toString().compareTo(o.dstName.toString());
  }

  public String toString() {
    return String.format("CustomAnimation{%s %s %dx%d -> %s%s @ %d,%d (%d frames)}", new Object[] {this.propertiesName, this.srcName, Integer.valueOf(this.w), Integer.valueOf(this.h), this.dstName, this.mipmapLevel > 0 ? "#" + this.mipmapLevel : "", Integer.valueOf(this.x), Integer.valueOf(this.y), Integer.valueOf(this.numFrames)});
  }

  private static void ARGBtoRGBA(int[] src, byte[] dest) {
    for (int i = 0; i < src.length; ++i) {
      int v = src[i];
      dest[i * 4 + 3] = (byte)(v >> 24 & 255);
      dest[i * 4 + 0] = (byte)(v >> 16 & 255);
      dest[i * 4 + 1] = (byte)(v >> 8 & 255);
      dest[i * 4 + 2] = (byte)(v >> 0 & 255);
    }
  }

  private static BufferedImage resizeImage(BufferedImage image, int width) {
    if (width == image.getWidth()) {
      return image;
    } else {
      int height = image.getHeight() * width / image.getWidth();
      logger.finer("resizing to %dx%d", new Object[] {Integer.valueOf(width), Integer.valueOf(height)});
      BufferedImage newImage = new BufferedImage(width, height, 2);
      Graphics2D graphics2D = newImage.createGraphics();
      graphics2D.drawImage(image, 0, 0, width, height, (ImageObserver)null);
      return newImage;
    }
  }

  private void loadProperties(Properties properties) {
    this.loadTileOrder(properties);
    int i;

    if (this.tileOrder == null) {
      this.tileOrder = new int[this.numFrames];

      for (i = 0; i < this.numFrames; ++i) {
        this.tileOrder[i] = i % this.numTiles;
      }
    }

    this.tileDelay = new int[this.numFrames];
    this.loadTileDelay(properties);

    for (i = 0; i < this.numFrames; ++i) {
      this.tileDelay[i] = Math.max(this.tileDelay[i], 1);
    }
  }

  private void loadTileOrder(Properties properties) {
    if (properties != null) {
      int i;

      for (i = 0; getIntValue(properties, "tile.", i) != null; ++i) {
        ;
      }

      if (i > 0) {
        this.numFrames = i;
        this.tileOrder = new int[this.numFrames];

        for (i = 0; i < this.numFrames; ++i) {
          this.tileOrder[i] = Math.abs(getIntValue(properties, "tile.", i).intValue()) % this.numTiles;
        }
      }
    }
  }

  private void loadTileDelay(Properties properties) {
    if (properties != null) {
      Integer defaultValue = getIntValue(properties, "duration");

      for (int i = 0; i < this.numFrames; ++i) {
        Integer value = getIntValue(properties, "duration.", i);

        if (value != null) {
          this.tileDelay[i] = value.intValue();
        } else if (defaultValue != null) {
          this.tileDelay[i] = defaultValue.intValue();
        }
      }
    }
  }

  private static Integer getIntValue(Properties properties, String key) {
    try {
      String e = properties.getProperty(key);

      if (e != null && e.matches("^\\d+$")) {
        return Integer.valueOf(Integer.parseInt(e));
      }
    } catch (NumberFormatException var3) {
      ;
    }

    return null;
  }

  private static Integer getIntValue(Properties properties, String prefix, int index) {
    return getIntValue(properties, prefix + index);
  }

  private void update(int texture, int dx, int dy) {
    GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, this.mipmapLevel, this.x + dx, this.y + dy, this.w, this.h, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)this.imageData.position(4 * this.w * this.h * this.tileOrder[this.currentFrame]));
  }

  private int getDelay() {
    return this.tileDelay[this.currentFrame];
  }

  static Map access$000() {
    return pending;
  }

  static MCLogger access$100() {
    return logger;
  }

  static List access$200() {
    return animations;
  }

  static boolean access$300() {
    return enable;
  }

  static {
    TexturePackChangeHandler.register(new CustomAnimation$1("Extended HD", 1));
  }
}
TOP

Related Classes of com.prupe.mcpatcher.hd.CustomAnimation

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.