diff --git a/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java index fc9dfe9a45..458cbb37ff 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java +++ b/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java @@ -30,35 +30,16 @@ package net.runelite.cache.definitions; -import net.runelite.cache.definitions.loaders.SpriteLoader; - public class SpriteDefinition { - private SpriteLoader loader; private int offsetX; private int offsetY; private int width; private int height; - private byte[] pixels; // indexes into palette - private byte[] alphas; + private int[] pixels; private int maxWidth; private int maxHeight; - public SpriteDefinition(SpriteLoader loader) - { - this.loader = loader; - } - - public SpriteLoader getLoader() - { - return loader; - } - - public void setLoader(SpriteLoader loader) - { - this.loader = loader; - } - public int getOffsetX() { return offsetX; @@ -99,26 +80,16 @@ public class SpriteDefinition this.height = height; } - public byte[] getPixels() + public int[] getPixels() { return pixels; } - public void setPixels(byte[] pixels) + public void setPixels(int[] pixels) { this.pixels = pixels; } - public byte[] getAlphas() - { - return alphas; - } - - public void setAlphas(byte[] alphas) - { - this.alphas = alphas; - } - public int getMaxWidth() { return maxWidth; diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java index 770f9aded3..29a66f7b38 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java @@ -38,31 +38,29 @@ public class SpriteLoader public static final int FLAG_VERTICAL = 0b01; public static final int FLAG_ALPHA = 0b10; - private SpriteDefinition[] sprites; - - private int[] loadedPalette; - private int width; - private int height; - - public void load(InputStream stream) + public SpriteDefinition[] load(InputStream stream) { stream.setOffset(stream.getLength() - 2); int spriteCount = stream.readUnsignedShort(); - sprites = new SpriteDefinition[spriteCount]; - for (int i = 0; i < spriteCount; ++i) - { - sprites[i] = new SpriteDefinition(this); - } + SpriteDefinition[] sprites = new SpriteDefinition[spriteCount]; // 2 for size // 5 for width, height, palette length // + 8 bytes per sprite for offset x/y, width, and height stream.setOffset(stream.getLength() - 7 - spriteCount * 8); - width = stream.readUnsignedShort(); - height = stream.readUnsignedShort(); - int paletteLength = (stream.readUnsignedByte() & 255) + 1; + // max width and height + int width = stream.readUnsignedShort(); + int height = stream.readUnsignedShort(); + int paletteLength = stream.readUnsignedByte() + 1; + + for (int i = 0; i < spriteCount; ++i) + { + sprites[i] = new SpriteDefinition(); + sprites[i].setMaxWidth(width); + sprites[i].setMaxHeight(height); + } for (int i = 0; i < spriteCount; ++i) { @@ -86,15 +84,15 @@ public class SpriteLoader // same as above + 3 bytes for each palette entry, except for the first one (which is transparent) stream.setOffset(stream.getLength() - 7 - spriteCount * 8 - (paletteLength - 1) * 3); - loadedPalette = new int[paletteLength]; + int[] palette = new int[paletteLength]; for (int i = 1; i < paletteLength; ++i) { - loadedPalette[i] = stream.read24BitInt(); + palette[i] = stream.read24BitInt(); - if (loadedPalette[i] == 0) + if (palette[i] == 0) { - loadedPalette[i] = 1; + palette[i] = 1; } } @@ -103,10 +101,9 @@ public class SpriteLoader for (int i = 0; i < spriteCount; ++i) { SpriteDefinition def = sprites[i]; - int width = def.getWidth(); - int height = def.getHeight(); - // XXX OFFSETS - int dimension = width * height; + int spriteWidth = def.getWidth(); + int spriteHeight = def.getHeight(); + int dimension = spriteWidth * spriteHeight; byte[] pixelPaletteIndicies = new byte[dimension]; byte[] pixelAlphas = new byte[dimension]; @@ -123,11 +120,11 @@ public class SpriteLoader else { // read vertically - for (int j = 0; j < width; ++j) + for (int j = 0; j < spriteWidth; ++j) { - for (int k = 0; k < height; ++k) + for (int k = 0; k < spriteHeight; ++k) { - pixelPaletteIndicies[width * k + j] = stream.readByte(); + pixelPaletteIndicies[spriteWidth * k + j] = stream.readByte(); } } } @@ -146,11 +143,11 @@ public class SpriteLoader else { // read vertically - for (int j = 0; j < width; ++j) + for (int j = 0; j < spriteWidth; ++j) { - for (int k = 0; k < height; ++k) + for (int k = 0; k < spriteHeight; ++k) { - pixelAlphas[width * k + j] = stream.readByte(); + pixelAlphas[spriteWidth * k + j] = stream.readByte(); } } } @@ -167,18 +164,19 @@ public class SpriteLoader } } - def.setPixels(pixelPaletteIndicies); - def.setAlphas(pixelAlphas); - } - } + int[] pixels = new int[dimension]; + + // build argb pixels from palette/alphas + for (int j = 0; j < dimension; ++j) + { + int index = pixelPaletteIndicies[j] & 0xFF; + + pixels[j] = palette[index] | (pixelAlphas[j] << 24); + } + + def.setPixels(pixels); + } - public SpriteDefinition[] getSprites() - { return sprites; } - - public int[] getLoadedPalette() - { - return loadedPalette; - } } diff --git a/cache/src/main/java/net/runelite/cache/renderable/RGBSprite.java b/cache/src/main/java/net/runelite/cache/renderable/RGBSprite.java deleted file mode 100644 index c6a984382d..0000000000 --- a/cache/src/main/java/net/runelite/cache/renderable/RGBSprite.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016, 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Adam - * 4. Neither the name of the Adam nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Adam ''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 Adam 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 net.runelite.cache.renderable; - -import java.awt.image.BufferedImage; -import net.runelite.cache.definitions.SpriteDefinition; - -public class RGBSprite -{ - private int offsetY; - private int spriteWidth; - private int spriteHeight; - private int offsetX; - private int maxHeight; - private int maxWidth; - private int[] pixels; - - RGBSprite() - { - } - - public int getOffsetY() - { - return offsetY; - } - - public int getSpriteWidth() - { - return spriteWidth; - } - - public int getSpriteHeight() - { - return spriteHeight; - } - - public int getOffsetX() - { - return offsetX; - } - - public int getMaxHeight() - { - return maxHeight; - } - - public int getMaxWidth() - { - return maxWidth; - } - - public int[] getPixels() - { - return pixels; - } - - public static RGBSprite fromSpriteDefinition(SpriteDefinition def) - { - RGBSprite sprite = new RGBSprite(); - - sprite.maxWidth = def.getMaxWidth(); - sprite.maxHeight = def.getMaxHeight(); - sprite.offsetX = def.getOffsetX(); - sprite.offsetY = def.getOffsetY(); - sprite.spriteWidth = def.getWidth(); - sprite.spriteHeight = def.getHeight(); - - int dimension = sprite.spriteWidth * sprite.spriteHeight; - byte[] pixels = def.getPixels(); - - int[] palette = def.getLoader().getLoadedPalette(); - byte[] alphas = def.getAlphas(); - - sprite.pixels = new int[dimension]; - - for (int pos = 0; pos < dimension; ++pos) - { - int index = pixels[pos] & 0xff; - - sprite.pixels[pos] = palette[index] | (alphas[pos] << 24); - } - - return sprite; - } - - public BufferedImage getBufferedImage() - { - BufferedImage bi = new BufferedImage(spriteWidth, spriteHeight, BufferedImage.TYPE_INT_ARGB); - bi.setRGB(0, 0, spriteWidth, spriteHeight, pixels, 0, spriteWidth); - return bi; - } -} diff --git a/cache/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java b/cache/src/test/java/net/runelite/cache/SpriteDumperTest.java similarity index 84% rename from cache/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java rename to cache/src/test/java/net/runelite/cache/SpriteDumperTest.java index ad84596159..70ce0e9835 100644 --- a/cache/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java +++ b/cache/src/test/java/net/runelite/cache/SpriteDumperTest.java @@ -28,14 +28,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.cache.loaders; +package net.runelite.cache; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.List; import javax.imageio.ImageIO; -import net.runelite.cache.IndexType; -import net.runelite.cache.StoreLocation; import net.runelite.cache.definitions.SpriteDefinition; import net.runelite.cache.definitions.loaders.SpriteLoader; import net.runelite.cache.fs.Archive; @@ -43,7 +41,6 @@ import net.runelite.cache.fs.File; import net.runelite.cache.fs.Index; import net.runelite.cache.fs.Store; import net.runelite.cache.io.InputStream; -import net.runelite.cache.renderable.RGBSprite; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -51,9 +48,9 @@ import org.junit.rules.TemporaryFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SpriteLoaderTest +public class SpriteDumperTest { - private static final Logger logger = LoggerFactory.getLogger(SpriteLoaderTest.class); + private static final Logger logger = LoggerFactory.getLogger(SpriteDumperTest.class); @Rule public TemporaryFolder folder = StoreLocation.getTemporaryFolder(); @@ -82,24 +79,23 @@ public class SpriteLoaderTest byte[] contents = file.getContents(); SpriteLoader loader = new SpriteLoader(); - loader.load(new InputStream(contents)); - - SpriteDefinition[] defs = loader.getSprites(); - - for (int i = 0; i < defs.length; ++i) - { - RGBSprite sp = RGBSprite.fromSpriteDefinition(defs[i]); + SpriteDefinition[] sprites = loader.load(new InputStream(contents)); + int frame = 0; + + for (SpriteDefinition def : sprites) + { // I don't know why this happens - if (sp.getSpriteHeight() <= 0 || sp.getSpriteWidth() <= 0) + if (def.getHeight() <= 0 || def.getWidth() <= 0) continue; - BufferedImage image = sp.getBufferedImage(); - java.io.File targ = new java.io.File(outDir, a.getArchiveId() + "-" + i + ".png"); + BufferedImage image = getBufferedImage(def); + java.io.File targ = new java.io.File(outDir, a.getArchiveId() + "-" + frame + ".png"); targ.mkdirs(); ImageIO.write(image, "png", targ); ++count; + ++frame; } } } @@ -108,4 +104,11 @@ public class SpriteLoaderTest logger.info("Dumped {} sprites to {}", count, outDir); } + + private BufferedImage getBufferedImage(SpriteDefinition def) + { + BufferedImage bi = new BufferedImage(def.getWidth(), def.getHeight(), BufferedImage.TYPE_INT_ARGB); + bi.setRGB(0, 0, def.getWidth(), def.getHeight(), def.getPixels(), 0, def.getWidth()); + return bi; + } } diff --git a/cache/src/test/java/net/runelite/cache/loaders/TitleDumper.java b/cache/src/test/java/net/runelite/cache/TitleDumper.java similarity index 98% rename from cache/src/test/java/net/runelite/cache/loaders/TitleDumper.java rename to cache/src/test/java/net/runelite/cache/TitleDumper.java index 3ca8ca00d5..9f21585aed 100644 --- a/cache/src/test/java/net/runelite/cache/loaders/TitleDumper.java +++ b/cache/src/test/java/net/runelite/cache/TitleDumper.java @@ -28,7 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.cache.loaders; +package net.runelite.cache; import java.io.IOException; import java.nio.file.Files;