diff --git a/client/src/main/java/plugin/api/API.java b/client/src/main/java/plugin/api/API.java
index 7a43fb3..57208be 100644
--- a/client/src/main/java/plugin/api/API.java
+++ b/client/src/main/java/plugin/api/API.java
@@ -7,6 +7,7 @@ import rt4.Font;
import java.awt.*;
import java.awt.event.*;
+import java.awt.image.BufferedImage;
import java.util.ArrayList;
import static rt4.MathUtils.clamp;
@@ -81,6 +82,10 @@ public class API {
return Inv.getObjectSprite(outlineType, objId, drawText, qty, shadowIntensity);
}
+ public static Sprite GetSpriteFromPNG(BufferedImage image) {
+ return SpritePNGLoader.getImageIndexedSprite(image);
+ }
+
public static WindowMode GetWindowMode() {
int mode = DisplayMode.getWindowMode();
switch(mode) {
diff --git a/client/src/main/java/plugin/api/SpritePNGLoader.java b/client/src/main/java/plugin/api/SpritePNGLoader.java
new file mode 100644
index 0000000..c937a2c
--- /dev/null
+++ b/client/src/main/java/plugin/api/SpritePNGLoader.java
@@ -0,0 +1,106 @@
+package plugin.api;
+
+import rt4.GlAlphaSprite;
+import rt4.SoftwareAlphaSprite;
+import rt4.Sprite;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DirectColorModel;
+import java.awt.image.PixelGrabber;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SpritePNGLoader {
+
+ /**
+ * Converts the buffered image into a sprite image and returns it
+ *
+ * @param image The image to be converted
+ * @return The buffered image as a sprite image
+ */
+ public static SpritePixels getImageSpritePixels(BufferedImage image) {
+ int[] pixels = new int[image.getWidth() * image.getHeight()];
+
+ try {
+ PixelGrabber g = new PixelGrabber(image, 0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
+ g.setColorModel(new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000));
+ g.grabPixels();
+
+ // Make any fully transparent pixels fully black, because the sprite draw routines
+ // check for == 0, not actual transparency
+ for (int i = 0; i < pixels.length; i++) {
+ if ((pixels[i] & 0xFF000000) == 0) {
+ pixels[i] = 0;
+ }
+ }
+ } catch (InterruptedException ex) {
+ System.err.println("PixelGrabber was interrupted: " + ex);
+ }
+
+ return new SpritePixels(pixels, image.getWidth(), image.getHeight());
+ }
+
+ /**
+ * Converts an image into an {@code IndexedSprite} instance.
+ *
+ * The passed in image can only have at max 255 different colors.
+ *
+ * @param image The image to be converted
+ * @return The image as an {@code IndexedSprite}
+ */
+ public static Sprite getImageIndexedSprite(BufferedImage image) {
+ final byte[] pixels = new byte[image.getWidth() * image.getHeight()];
+ final List palette = new ArrayList<>();
+ /*
+ When drawing the indexed sprite, palette idx 0 is seen as fully transparent,
+ so pad the palette out so that our colors start at idx 1.
+ */
+ palette.add(0);
+
+ final int[] sourcePixels = image.getRGB(0, 0,
+ image.getWidth(), image.getHeight(),
+ null, 0, image.getWidth());
+
+ /*
+ Build a color palette and assign the pixels to positions in the palette.
+ */
+ for (int j = 0; j < sourcePixels.length; j++) {
+ final int argb = sourcePixels[j];
+ final int a = (argb >> 24) & 0xFF;
+ final int rgb = argb & 0xFF_FF_FF;
+
+ // Default to not drawing the pixel.
+ int paletteIdx = 0;
+
+ // If the pixel is fully opaque, draw it.
+ if (a == 0xFF) {
+ paletteIdx = palette.indexOf(rgb);
+
+ if (paletteIdx == -1) {
+ paletteIdx = palette.size();
+ palette.add(rgb);
+ }
+ }
+
+ pixels[j] = (byte) paletteIdx;
+ }
+
+ if (palette.size() > 256) {
+ throw new RuntimeException("Passed in image had " + (palette.size() - 1)
+ + " different colors, exceeding the max of 255.");
+ }
+
+ //int[] imgPalette = palette.stream().mapToInt(i -> i).toArray();
+
+ Sprite sprites;
+ //IndexedSprite sprite;
+ if (API.IsHD()) { //width, height, xOffsets[local16], yOffsets[local16], innerWidths[local16], innerHeights[local16], local38
+ sprites = new GlAlphaSprite(image.getWidth(), image.getHeight(), 0, 0, image.getWidth(), image.getHeight(), sourcePixels);
+ // sprite = new GlIndexedSprite(image.getWidth(), image.getHeight(), 0, 0, image.getWidth(), image.getHeight(), pixels, imgPalette);
+ } else {
+ sprites = new SoftwareAlphaSprite(image.getWidth(), image.getHeight(), 0, 0, image.getWidth(), image.getHeight(), sourcePixels);
+ // sprite = new SoftwareIndexedSprite(image.getWidth(), image.getHeight(), 0, 0, image.getWidth(), image.getHeight(), pixels, imgPalette);
+ }
+ return sprites;
+ }
+}
\ No newline at end of file
diff --git a/client/src/main/java/plugin/api/SpritePixels.java b/client/src/main/java/plugin/api/SpritePixels.java
new file mode 100644
index 0000000..203fdcb
--- /dev/null
+++ b/client/src/main/java/plugin/api/SpritePixels.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018, Adam
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package plugin.api;
+
+import java.awt.image.BufferedImage;
+
+class SpritePixels {
+ public int[] pixels;
+ public int width;
+ public int height;
+ public int offsetX;
+ int offsetY;
+
+ public SpritePixels(int[] var1, int var2, int var3) {
+ this.pixels = var1;
+ this.width = var2;
+ this.height = var3;
+ this.offsetY = 0;
+ this.offsetX = 0;
+ }
+
+ public SpritePixels(int var1, int var2) {
+ this(new int[var2 * var1], var1, var2);
+ }
+
+ public void drawBorder(int color) {
+ int[] newPixels = new int[this.width * this.height];
+ int pixelIndex = 0;
+
+ for (int y = 0; y < this.height; ++y) {
+ for (int x = 0; x < this.width; ++x) {
+ int pixel = this.pixels[pixelIndex];
+ if (pixel == 0) {
+ // W
+ if (x > 0 && this.pixels[pixelIndex - 1] != 0) {
+ pixel = color;
+ }
+ // N
+ else if (y > 0 && this.pixels[pixelIndex - this.width] != 0) {
+ pixel = color;
+ }
+ // E
+ else if (x < this.width - 1 && this.pixels[pixelIndex + 1] != 0) {
+ pixel = color;
+ }
+ // S
+ else if (y < this.height - 1 && this.pixels[pixelIndex + this.width] != 0) {
+ pixel = color;
+ }
+ }
+
+ newPixels[pixelIndex++] = pixel;
+ }
+ }
+
+ this.pixels = newPixels;
+ }
+
+
+ public void drawShadow(int color) {
+ for (int y = this.height - 1; y > 0; --y) {
+ int rowOffset = y * this.width;
+
+ for (int x = this.width - 1; x > 0; --x) {
+ // if *this* pixel is black/unset AND the pixel to the NW isn't black/unset
+ if (this.pixels[x + rowOffset] == 0 && this.pixels[x + rowOffset - 1 - this.width] != 0) {
+ this.pixels[x + rowOffset] = color;
+ }
+ }
+ }
+
+ }
+
+ static void method5843(int[] rasterizerPixels, int[] spritePixels, int var2, int var3, int pixelIndex, int width, int height, int var7, int var8) {
+ int var9 = -(width >> 2);
+ width = -(width & 3);
+
+ for (int var10 = -height; var10 < 0; ++var10) {
+ for (int i = var9 * 4; i < 0; ++i) {
+ var2 = spritePixels[var3++];
+ if (var2 != 0) {
+ rasterizerPixels[pixelIndex++] = var2;
+ } else {
+ ++pixelIndex;
+ }
+ }
+
+ for (int i = width; i < 0; ++i) {
+ var2 = spritePixels[var3++];
+ if (var2 != 0) {
+ rasterizerPixels[pixelIndex++] = var2;
+ } else {
+ ++pixelIndex;
+ }
+ }
+
+ pixelIndex += var7;
+ var3 += var8;
+ }
+
+ }
+
+ public BufferedImage toBufferedImage() {
+ int[] transPixels = new int[pixels.length];
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+
+ for (int i = 0; i < pixels.length; i++) {
+ if (pixels[i] != 0) {
+ transPixels[i] = pixels[i] | 0xff000000;
+ }
+ }
+
+ img.setRGB(0, 0, width, height, transPixels, 0, width);
+ return img;
+ }
+
+}
\ No newline at end of file