runelite-mixins: add bilinear interpolation to minimap

This commit is contained in:
Dennis
2018-07-25 00:03:05 +02:00
committed by Lucwousin
parent 2b32d49e53
commit 2b9277c3c2
2 changed files with 119 additions and 9 deletions

View File

@@ -1,14 +1,48 @@
/*
* Copyright (c) 2016-2017, 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 net.runelite.mixins;
import java.awt.Color;
import java.awt.image.BufferedImage;
import net.runelite.api.mixins.Copy;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Replace;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSSprite;
@Mixin(RSSprite.class)
public abstract class RSSpriteMixin implements RSSprite
{
@Shadow("client")
private static RSClient client;
@Shadow("hdMinimapEnabled")
private boolean hdMinimapEnabled;
@Inject
@Override
public BufferedImage toBufferedImage()
@@ -109,4 +143,83 @@ public abstract class RSSpriteMixin implements RSSprite
img.setRGB(0, 0, width, height, newPixels, 0, width);
}
@Copy("drawRotatedMaskedCenteredAround")
abstract void rs$drawAsCircleAt(int x, int y, int width, int height, int xOffset, int yOffset,
int rotation, int zoom, int[] xOffsets, int[] yOffsets);
@Replace("drawRotatedMaskedCenteredAround")
public void rl$drawAsCircleAt(int x, int y, int width, int height, int xOffset, int yOffset, int rotation,
int zoom, int[] xOffsets, int[] yOffsets)
{
if (!hdMinimapEnabled)
{
rs$drawAsCircleAt(x, y, width, height, xOffset, yOffset, rotation, zoom, xOffsets, yOffsets);
return;
}
try
{
int[] graphicsPixels = client.getGraphicsPixels();
int[] spritePixels = getPixels();
int spriteWidth = getWidth();
int centerX = -width / 2;
int centerY = -height / 2;
int rotSin = (int) (Math.sin((double) rotation / 326.11D) * 65536.0D);
int rotCos = (int) (Math.cos((double) rotation / 326.11D) * 65536.0D);
rotSin = rotSin * zoom >> 8;
rotCos = rotCos * zoom >> 8;
int posX = centerY * rotSin + centerX * rotCos + (xOffset << 16);
int posY = centerY * rotCos - centerX * rotSin + (yOffset << 16);
int pixelIndex = x + y * client.getGraphicsPixelsWidth();
for (y = 0; y < height; ++y)
{
int spriteOffsetX = xOffsets[y];
int graphicsPixelIndex = pixelIndex + spriteOffsetX;
int spriteX = posX + rotCos * spriteOffsetX;
int spriteY = posY - rotSin * spriteOffsetX;
for (x = -yOffsets[y]; x < 0; ++x)
{
// bilinear interpolation
int x1 = spriteX >> 16;
int y1 = spriteY >> 16;
int x2 = x1 + 1;
int y2 = y1 + 1;
int c1 = spritePixels[x1 + y1 * spriteWidth];
int c2 = spritePixels[x2 + y1 * spriteWidth];
int c3 = spritePixels[x1 + y2 * spriteWidth];
int c4 = spritePixels[x2 + y2 * spriteWidth];
int u1 = (spriteX >> 8) - (x1 << 8);
int v1 = (spriteY >> 8) - (y1 << 8);
int u2 = (x2 << 8) - (spriteX >> 8);
int v2 = (y2 << 8) - (spriteY >> 8);
int a1 = u2 * v2;
int a2 = u1 * v2;
int a3 = u2 * v1;
int a4 = u1 * v1;
int r = (c1 >> 16 & 0xff) * a1 + (c2 >> 16 & 0xff) * a2 +
(c3 >> 16 & 0xff) * a3 + (c4 >> 16 & 0xff) * a4 & 0xff0000;
int g = (c1 >> 8 & 0xff) * a1 + (c2 >> 8 & 0xff) * a2 +
(c3 >> 8 & 0xff) * a3 + (c4 >> 8 & 0xff) * a4 >> 8 & 0xff00;
int b = (c1 & 0xff) * a1 + (c2 & 0xff) * a2 +
(c3 & 0xff) * a3 + (c4 & 0xff) * a4 >> 16;
graphicsPixels[graphicsPixelIndex++] = r | g | b; // XXX: Might need "| 0xFF000000"
spriteX += rotCos;
spriteY -= rotSin;
}
posX += rotSin;
posY += rotCos;
pixelIndex += client.getGraphicsPixelsWidth();
}
}
catch (Exception e)
{
// ignored
}
}
}

View File

@@ -1,16 +1,13 @@
/*
* BSD 2-Clause License
*
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
* Copyright (c) 2016-2017, 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:
*
* Redistributions of source code must retain the above copyright notice, this
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* 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.
*