mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-09 16:45:46 -07:00
Added external PNG to JaGex sprite format support
This commit is contained in:
parent
6ae6b19e44
commit
7b3d3f0919
3 changed files with 250 additions and 0 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
106
client/src/main/java/plugin/api/SpritePNGLoader.java
Normal file
106
client/src/main/java/plugin/api/SpritePNGLoader.java
Normal file
|
|
@ -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.
|
||||
* <p>
|
||||
* 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<Integer> 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;
|
||||
}
|
||||
}
|
||||
139
client/src/main/java/plugin/api/SpritePixels.java
Normal file
139
client/src/main/java/plugin/api/SpritePixels.java
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue