Add GPU renderer
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
package net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import net.runelite.rs.api.RSModel;
|
||||
|
||||
/**
|
||||
* Class to check clickboxes of models. Mostly refactored code from the client.
|
||||
*/
|
||||
@Mixin(RSClient.class)
|
||||
public abstract class ClickboxMixin implements RSClient
|
||||
{
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
private static final int MAX_ENTITES_AT_MOUSE = 1000;
|
||||
private static final int CLICKBOX_CLOSE = 50;
|
||||
private static final int CLICKBOX_FAR = 3500;
|
||||
|
||||
@Inject
|
||||
private static final int[] rl$modelViewportXs = new int[4700];
|
||||
|
||||
@Inject
|
||||
private static final int[] rl$modelViewportYs = new int[4700];
|
||||
|
||||
@Inject
|
||||
public void checkClickbox(Model rlModel, int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int _x, int _y, int _z, long hash)
|
||||
{
|
||||
RSModel model = (RSModel) rlModel;
|
||||
boolean hasFlag = hash != 0L && (int) (hash >>> 16 & 1L) != 1;
|
||||
boolean viewportContainsMouse = client.getViewportContainsMouse();
|
||||
|
||||
if (!hasFlag || !viewportContainsMouse || client.getOculusOrbState() != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean bb = boundingboxCheck(model, _x, _y, _z);
|
||||
if (!bb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// only need a boundingbox check?
|
||||
if (model.isClickable())
|
||||
{
|
||||
addHashAtMouse(hash);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise we must check if the mouse is in a triangle
|
||||
final int vertexCount = model.getVerticesCount();
|
||||
final int triangleCount = model.getTrianglesCount();
|
||||
|
||||
final int[] vertexX = model.getVerticesX();
|
||||
final int[] vertexY = model.getVerticesY();
|
||||
final int[] vertexZ = model.getVerticesZ();
|
||||
|
||||
final int[] triangleX = model.getTrianglesX();
|
||||
final int[] triangleY = model.getTrianglesY();
|
||||
final int[] triangleZ = model.getTrianglesZ();
|
||||
|
||||
final int[] color3 = model.getFaceColors3();
|
||||
|
||||
final int zoom = client.get3dZoom();
|
||||
|
||||
final int centerX = client.getCenterX();
|
||||
final int centerY = client.getCenterY();
|
||||
|
||||
int sin = 0;
|
||||
int cos = 0;
|
||||
if (orientation != 0)
|
||||
{
|
||||
sin = Perspective.SINE[orientation];
|
||||
cos = Perspective.COSINE[orientation];
|
||||
}
|
||||
|
||||
for (int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
int x = vertexX[i];
|
||||
int y = vertexY[i];
|
||||
int z = vertexZ[i];
|
||||
|
||||
int var42;
|
||||
if (orientation != 0)
|
||||
{
|
||||
var42 = z * sin + x * cos >> 16;
|
||||
z = z * cos - x * sin >> 16;
|
||||
x = var42;
|
||||
}
|
||||
|
||||
x += _x;
|
||||
y += _y;
|
||||
z += _z;
|
||||
|
||||
var42 = z * yawSin + yawCos * x >> 16;
|
||||
z = yawCos * z - x * yawSin >> 16;
|
||||
x = var42;
|
||||
var42 = pitchCos * y - z * pitchSin >> 16;
|
||||
z = y * pitchSin + pitchCos * z >> 16;
|
||||
|
||||
if (z >= 50)
|
||||
{
|
||||
rl$modelViewportYs[i] = x * zoom / z + centerX;
|
||||
rl$modelViewportXs[i] = var42 * zoom / z + centerY;
|
||||
}
|
||||
else
|
||||
{
|
||||
rl$modelViewportYs[i] = -5000;
|
||||
}
|
||||
}
|
||||
|
||||
final int viewportMouseX = client.getViewportMouseX();
|
||||
final int viewportMouseY = client.getViewportMouseY();
|
||||
|
||||
for (int i = 0; i < triangleCount; ++i)
|
||||
{
|
||||
if (color3[i] == -2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final int vA = triangleX[i];
|
||||
final int vB = triangleY[i];
|
||||
final int vC = triangleZ[i];
|
||||
|
||||
int y1 = rl$modelViewportYs[vA];
|
||||
int y2 = rl$modelViewportYs[vB];
|
||||
int y3 = rl$modelViewportYs[vC];
|
||||
|
||||
int x1 = rl$modelViewportXs[vA];
|
||||
int x2 = rl$modelViewportXs[vB];
|
||||
int x3 = rl$modelViewportXs[vC];
|
||||
|
||||
if (y1 == -5000 || y2 == -5000 || y3 == -5000)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final int radius = model.isClickable() ? 20 : 5;
|
||||
|
||||
int var18 = radius + viewportMouseY;
|
||||
boolean var34;
|
||||
if (var18 < x1 && var18 < x2 && var18 < x3)
|
||||
{
|
||||
var34 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var18 = viewportMouseY - radius;
|
||||
if (var18 > x1 && var18 > x2 && var18 > x3)
|
||||
{
|
||||
var34 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var18 = radius + viewportMouseX;
|
||||
if (var18 < y1 && var18 < y2 && var18 < y3)
|
||||
{
|
||||
var34 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var18 = viewportMouseX - radius;
|
||||
if (var18 > y1 && var18 > y2 && var18 > y3)
|
||||
{
|
||||
var34 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var34 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (var34)
|
||||
{
|
||||
addHashAtMouse(hash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
private void addHashAtMouse(long hash)
|
||||
{
|
||||
long[] entitiesAtMouse = client.getEntitiesAtMouse();
|
||||
int count = client.getEntitiesAtMouseCount();
|
||||
if (count < MAX_ENTITES_AT_MOUSE)
|
||||
{
|
||||
entitiesAtMouse[count] = hash;
|
||||
client.setEntitiesAtMouseCount(count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
private boolean boundingboxCheck(Model model, int x, int y, int z)
|
||||
{
|
||||
final int cameraPitch = client.getCameraPitch();
|
||||
final int cameraYaw = client.getCameraYaw();
|
||||
|
||||
final int pitchSin = Perspective.SINE[cameraPitch];
|
||||
final int pitchCos = Perspective.COSINE[cameraPitch];
|
||||
|
||||
final int yawSin = Perspective.SINE[cameraYaw];
|
||||
final int yawCos = Perspective.COSINE[cameraYaw];
|
||||
|
||||
final int centerX = client.getCenterX();
|
||||
final int centerY = client.getCenterY();
|
||||
|
||||
final int viewportMouseX = client.getViewportMouseX();
|
||||
final int viewportMouseY = client.getViewportMouseY();
|
||||
|
||||
final int Rasterizer3D_zoom = client.get3dZoom();
|
||||
|
||||
int var6 = (viewportMouseX - centerX) * CLICKBOX_CLOSE / Rasterizer3D_zoom;
|
||||
int var7 = (viewportMouseY - centerY) * CLICKBOX_CLOSE / Rasterizer3D_zoom;
|
||||
int var8 = (viewportMouseX - centerX) * CLICKBOX_FAR / Rasterizer3D_zoom;
|
||||
int var9 = (viewportMouseY - centerY) * CLICKBOX_FAR / Rasterizer3D_zoom;
|
||||
int var10 = rl$rot1(var7, CLICKBOX_CLOSE, pitchCos, pitchSin);
|
||||
int var11 = rl$rot2(var7, CLICKBOX_CLOSE, pitchCos, pitchSin);
|
||||
var7 = var10;
|
||||
var10 = rl$rot1(var9, CLICKBOX_FAR, pitchCos, pitchSin);
|
||||
int var12 = rl$rot2(var9, CLICKBOX_FAR, pitchCos, pitchSin);
|
||||
var9 = var10;
|
||||
var10 = rl$rot3(var6, var11, yawCos, yawSin);
|
||||
var11 = rl$rot4(var6, var11, yawCos, yawSin);
|
||||
var6 = var10;
|
||||
var10 = rl$rot3(var8, var12, yawCos, yawSin);
|
||||
var12 = rl$rot4(var8, var12, yawCos, yawSin);
|
||||
int field1720 = (var10 - var6) / 2;
|
||||
int field638 = (var9 - var7) / 2;
|
||||
int field1846 = (var12 - var11) / 2;
|
||||
int field1722 = Math.abs(field1720);
|
||||
int field601 = Math.abs(field638);
|
||||
int field38 = Math.abs(field1846);
|
||||
|
||||
int var38 = x + model.getCenterX();
|
||||
int var39 = y + model.getCenterY();
|
||||
int var40 = z + model.getCenterZ();
|
||||
int var41 = model.getExtremeX();
|
||||
int var42 = model.getExtremeY();
|
||||
int var43 = model.getExtremeZ();
|
||||
|
||||
int field1861 = (var6 + var10) / 2;
|
||||
int field2317 = (var7 + var9) / 2;
|
||||
int field528 = (var12 + var11) / 2;
|
||||
|
||||
int var44 = field1861 - var38;
|
||||
int var45 = field2317 - var39;
|
||||
int var46 = field528 - var40;
|
||||
|
||||
boolean passes;
|
||||
if (Math.abs(var44) > var41 + field1722)
|
||||
{
|
||||
passes = false;
|
||||
}
|
||||
else if (Math.abs(var45) > var42 + field601)
|
||||
{
|
||||
passes = false;
|
||||
}
|
||||
else if (Math.abs(var46) > var43 + field38)
|
||||
{
|
||||
passes = false;
|
||||
}
|
||||
else if (Math.abs(var46 * field638 - var45 * field1846) > var42 * field38 + var43 * field601)
|
||||
{
|
||||
passes = false;
|
||||
}
|
||||
else if (Math.abs(var44 * field1846 - var46 * field1720) > var43 * field1722 + var41 * field38)
|
||||
{
|
||||
passes = false;
|
||||
}
|
||||
else if (Math.abs(var45 * field1720 - var44 * field638) > var42 * field1722 + var41 * field601)
|
||||
{
|
||||
passes = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
passes = true;
|
||||
}
|
||||
|
||||
return passes;
|
||||
}
|
||||
|
||||
@Inject
|
||||
private static int rl$rot1(int var0, int var1, int var2, int var3)
|
||||
{
|
||||
return var0 * var2 + var3 * var1 >> 16;
|
||||
}
|
||||
|
||||
@Inject
|
||||
private static int rl$rot2(int var0, int var1, int var2, int var3)
|
||||
{
|
||||
return var2 * var1 - var3 * var0 >> 16;
|
||||
}
|
||||
|
||||
@Inject
|
||||
private static int rl$rot3(int var0, int var1, int var2, int var3)
|
||||
{
|
||||
return var0 * var2 - var3 * var1 >> 16;
|
||||
}
|
||||
|
||||
@Inject
|
||||
private static int rl$rot4(int var0, int var1, int var2, int var3)
|
||||
{
|
||||
return var3 * var0 + var2 * var1 >> 16;
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,7 @@ import net.runelite.api.events.UsernameChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.hooks.Callbacks;
|
||||
import net.runelite.api.hooks.DrawCallbacks;
|
||||
import net.runelite.api.mixins.Copy;
|
||||
import net.runelite.api.mixins.FieldHook;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
@@ -124,6 +125,9 @@ public abstract class RSClientMixin implements RSClient
|
||||
@javax.inject.Inject
|
||||
private Callbacks callbacks;
|
||||
|
||||
@Inject
|
||||
private DrawCallbacks drawCallbacks;
|
||||
|
||||
@Inject
|
||||
@javax.inject.Inject
|
||||
@Named("Core Logger")
|
||||
@@ -156,6 +160,9 @@ public abstract class RSClientMixin implements RSClient
|
||||
@Inject
|
||||
private static RSItem lastItemDespawn;
|
||||
|
||||
@Inject
|
||||
private boolean gpu;
|
||||
|
||||
@Inject
|
||||
private static boolean oldIsResized;
|
||||
|
||||
@@ -166,6 +173,20 @@ public abstract class RSClientMixin implements RSClient
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public DrawCallbacks getDrawCallbacks()
|
||||
{
|
||||
return drawCallbacks;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setDrawCallbacks(DrawCallbacks drawCallbacks)
|
||||
{
|
||||
this.drawCallbacks = drawCallbacks;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Logger getLogger()
|
||||
@@ -1277,6 +1298,20 @@ public abstract class RSClientMixin implements RSClient
|
||||
RSClientMixin.lastItemDespawn = lastItemDespawn;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public boolean isGpu()
|
||||
{
|
||||
return gpu;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setGpu(boolean gpu)
|
||||
{
|
||||
this.gpu = gpu;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void queueChangedSkill(Skill skill)
|
||||
|
||||
@@ -26,6 +26,8 @@ package net.runelite.mixins;
|
||||
|
||||
import java.awt.event.FocusEvent;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.hooks.DrawCallbacks;
|
||||
import net.runelite.api.mixins.FieldHook;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.MethodHook;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
@@ -71,4 +73,27 @@ public abstract class RSGameEngineMixin implements RSGameEngine
|
||||
focusChanged.setFocused(true);
|
||||
client.getCallbacks().post(focusChanged);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@MethodHook("post")
|
||||
public void onPost(Object canvas)
|
||||
{
|
||||
DrawCallbacks drawCallbacks = client.getDrawCallbacks();
|
||||
if (drawCallbacks != null)
|
||||
{
|
||||
drawCallbacks.draw();
|
||||
}
|
||||
}
|
||||
|
||||
@FieldHook("replaceCanvasNextFrame")
|
||||
@Inject
|
||||
public void onReplaceCanvasNextFrameChanged(int idx)
|
||||
{
|
||||
// when this is initially called the client instance doesn't exist yet
|
||||
if (client != null && client.isGpu() && isReplaceCanvasNextFrame())
|
||||
{
|
||||
setReplaceCanvasNextFrame(false);
|
||||
setResizeCanvasNextFrame(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,17 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Hashtable;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.MethodHook;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Replace;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
@@ -37,6 +47,30 @@ public abstract class RSMainBufferProviderMixin implements RSMainBufferProvider
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private IntBuffer buffer;
|
||||
|
||||
@MethodHook(value = "<init>", end = true)
|
||||
@Inject
|
||||
public void init(int width, int height, Component canvas)
|
||||
{
|
||||
if (!client.isGpu())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int[] pixels = getPixels();
|
||||
|
||||
// we need to make our own buffered image for the client with the alpha channel enabled in order to
|
||||
// have alphas for the overlays applied correctly
|
||||
DataBufferInt dataBufferInt = new DataBufferInt(pixels, pixels.length);
|
||||
DirectColorModel directColorModel = new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
|
||||
WritableRaster writableRaster = Raster.createWritableRaster(directColorModel.createCompatibleSampleModel(width, height), dataBufferInt, null);
|
||||
BufferedImage bufferedImage = new BufferedImage(directColorModel, writableRaster, false, new Hashtable());
|
||||
|
||||
setImage(bufferedImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacing this method makes it so we can completely
|
||||
* control when/what is drawn on the game's canvas,
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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 net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.Model;
|
||||
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.RSModel;
|
||||
import net.runelite.rs.api.RSModelData;
|
||||
|
||||
@Mixin(RSModelData.class)
|
||||
public abstract class RSModelDataMixin implements RSModelData
|
||||
{
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private float[][] faceTextureUCoordinates;
|
||||
|
||||
@Inject
|
||||
private float[][] faceTextureVCoordinates;
|
||||
|
||||
@Copy("light")
|
||||
public abstract Model rs$light(int ambient, int contrast, int var3, int var4, int var5);
|
||||
|
||||
@Replace("light")
|
||||
public Model rl$light(int ambient, int contrast, int var3, int var4, int var5)
|
||||
{
|
||||
client.getLogger().debug("Lighting model {}", this);
|
||||
|
||||
Model model = rs$light(ambient, contrast, var3, var4, var5);
|
||||
if (model == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (faceTextureUCoordinates == null)
|
||||
{
|
||||
computeTextureUVCoordinates();
|
||||
}
|
||||
|
||||
RSModel rsModel = (RSModel) model;
|
||||
rsModel.setFaceTextureUCoordinates(faceTextureUCoordinates);
|
||||
rsModel.setFaceTextureVCoordinates(faceTextureVCoordinates);
|
||||
return model;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void computeTextureUVCoordinates()
|
||||
{
|
||||
final short[] faceTextures = getFaceTextures();
|
||||
if (faceTextures == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int[] vertexPositionsX = getVertexX();
|
||||
final int[] vertexPositionsY = getVertexY();
|
||||
final int[] vertexPositionsZ = getVertexZ();
|
||||
|
||||
final int[] trianglePointsX = getTrianglePointsX();
|
||||
final int[] trianglePointsY = getTrianglePointsY();
|
||||
final int[] trianglePointsZ = getTrianglePointsZ();
|
||||
|
||||
final short[] texTriangleX = getTexTriangleX();
|
||||
final short[] texTriangleY = getTexTriangleY();
|
||||
final short[] texTriangleZ = getTexTriangleZ();
|
||||
|
||||
final byte[] textureCoords = getTextureCoords();
|
||||
final byte[] textureRenderTypes = getTextureRenderTypes();
|
||||
|
||||
int faceCount = getTriangleFaceCount();
|
||||
this.faceTextureUCoordinates = new float[faceCount][];
|
||||
this.faceTextureVCoordinates = new float[faceCount][];
|
||||
|
||||
for (int i = 0; i < faceCount; i++)
|
||||
{
|
||||
int textureCoordinate;
|
||||
if (textureCoords == null)
|
||||
{
|
||||
textureCoordinate = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
textureCoordinate = textureCoords[i];
|
||||
}
|
||||
|
||||
short textureIdx;
|
||||
textureIdx = faceTextures[i];
|
||||
|
||||
if (textureIdx != -1)
|
||||
{
|
||||
float[] u = new float[3];
|
||||
float[] v = new float[3];
|
||||
|
||||
if (textureCoordinate == -1)
|
||||
{
|
||||
u[0] = 0.0F;
|
||||
v[0] = 1.0F;
|
||||
|
||||
u[1] = 1.0F;
|
||||
v[1] = 1.0F;
|
||||
|
||||
u[2] = 0.0F;
|
||||
v[2] = 0.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
textureCoordinate &= 0xFF;
|
||||
|
||||
byte textureRenderType = 0;
|
||||
if (textureRenderTypes != null)
|
||||
{
|
||||
textureRenderType = textureRenderTypes[textureCoordinate];
|
||||
}
|
||||
|
||||
if (textureRenderType == 0)
|
||||
{
|
||||
int faceVertexIdx1 = trianglePointsX[i];
|
||||
int faceVertexIdx2 = trianglePointsY[i];
|
||||
int faceVertexIdx3 = trianglePointsZ[i];
|
||||
|
||||
int triangleVertexIdx1 = texTriangleX[textureCoordinate];
|
||||
int triangleVertexIdx2 = texTriangleY[textureCoordinate];
|
||||
int triangleVertexIdx3 = texTriangleZ[textureCoordinate];
|
||||
|
||||
float triangleX = (float) vertexPositionsX[triangleVertexIdx1];
|
||||
float triangleY = (float) vertexPositionsY[triangleVertexIdx1];
|
||||
float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1];
|
||||
|
||||
float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX;
|
||||
float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY;
|
||||
float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ;
|
||||
float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX;
|
||||
float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY;
|
||||
float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ;
|
||||
float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX;
|
||||
float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY;
|
||||
float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ;
|
||||
float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX;
|
||||
float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY;
|
||||
float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ;
|
||||
float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX;
|
||||
float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY;
|
||||
float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ;
|
||||
|
||||
float f_897_ = f_883_ * f_887_ - f_884_ * f_886_;
|
||||
float f_898_ = f_884_ * f_885_ - f_882_ * f_887_;
|
||||
float f_899_ = f_882_ * f_886_ - f_883_ * f_885_;
|
||||
float f_900_ = f_886_ * f_899_ - f_887_ * f_898_;
|
||||
float f_901_ = f_887_ * f_897_ - f_885_ * f_899_;
|
||||
float f_902_ = f_885_ * f_898_ - f_886_ * f_897_;
|
||||
float f_903_ = 1.0F / (f_900_ * f_882_ + f_901_ * f_883_ + f_902_ * f_884_);
|
||||
|
||||
u[0] = (f_900_ * f_888_ + f_901_ * f_889_ + f_902_ * f_890_) * f_903_;
|
||||
u[1] = (f_900_ * f_891_ + f_901_ * f_892_ + f_902_ * f_893_) * f_903_;
|
||||
u[2] = (f_900_ * f_894_ + f_901_ * f_895_ + f_902_ * f_896_) * f_903_;
|
||||
|
||||
f_900_ = f_883_ * f_899_ - f_884_ * f_898_;
|
||||
f_901_ = f_884_ * f_897_ - f_882_ * f_899_;
|
||||
f_902_ = f_882_ * f_898_ - f_883_ * f_897_;
|
||||
f_903_ = 1.0F / (f_900_ * f_885_ + f_901_ * f_886_ + f_902_ * f_887_);
|
||||
|
||||
v[0] = (f_900_ * f_888_ + f_901_ * f_889_ + f_902_ * f_890_) * f_903_;
|
||||
v[1] = (f_900_ * f_891_ + f_901_ * f_892_ + f_902_ * f_893_) * f_903_;
|
||||
v[2] = (f_900_ * f_894_ + f_901_ * f_895_ + f_902_ * f_896_) * f_903_;
|
||||
}
|
||||
}
|
||||
|
||||
this.faceTextureUCoordinates[i] = u;
|
||||
this.faceTextureVCoordinates[i] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,11 +27,15 @@ package net.runelite.mixins;
|
||||
import java.awt.Polygon;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.mixins.Copy;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.MethodHook;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Replace;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.api.model.Jarvis;
|
||||
import net.runelite.api.model.Triangle;
|
||||
@@ -48,6 +52,63 @@ public abstract class RSModelMixin implements RSModel
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private int rl$sceneId;
|
||||
|
||||
@Inject
|
||||
private int rl$bufferOffset;
|
||||
|
||||
@Inject
|
||||
private int rl$uvBufferOffset;
|
||||
|
||||
@Inject
|
||||
private float[][] rl$faceTextureUCoordinates;
|
||||
|
||||
@Inject
|
||||
private float[][] rl$faceTextureVCoordinates;
|
||||
|
||||
@MethodHook(value = "<init>", end = true)
|
||||
@Inject
|
||||
public void rl$init(RSModel[] models, int length)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
RSModel model = models[i];
|
||||
if (model != null)
|
||||
{
|
||||
count += model.getTrianglesCount();
|
||||
}
|
||||
}
|
||||
|
||||
float[][] u = new float[count][];
|
||||
float[][] v = new float[count][];
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
RSModel model = models[i];
|
||||
if (model != null)
|
||||
{
|
||||
float[][] modelU = model.getFaceTextureUCoordinates();
|
||||
float[][] modelV = model.getFaceTextureVCoordinates();
|
||||
|
||||
for (int j = 0; j < model.getTrianglesCount(); ++j)
|
||||
{
|
||||
if (modelU != null && modelV != null)
|
||||
{
|
||||
u[idx] = modelU[j];
|
||||
v[idx] = modelV[j];
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFaceTextureUCoordinates(u);
|
||||
setFaceTextureVCoordinates(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Inject
|
||||
public List<Vertex> getVertices()
|
||||
@@ -99,6 +160,33 @@ public abstract class RSModelMixin implements RSModel
|
||||
return triangles;
|
||||
}
|
||||
|
||||
@Copy("contourGround")
|
||||
public abstract Model rs$contourGround(int[][] tileHeights, int packedX, int height, int packedY, boolean copy, int contouredGround);
|
||||
|
||||
@Replace("contourGround")
|
||||
public Model rl$contourGround(int[][] tileHeights, int packedX, int height, int packedY, boolean copy, int contouredGround)
|
||||
{
|
||||
// With contouredGround >= 0 lighted models are countoured, so we need to copy uvs
|
||||
Model model = rs$contourGround(tileHeights, packedX, height, packedY, copy, contouredGround);
|
||||
if (model != null && model != this)
|
||||
{
|
||||
RSModel rsModel = (RSModel) model;
|
||||
rsModel.setFaceTextureUCoordinates(rl$faceTextureUCoordinates);
|
||||
rsModel.setFaceTextureVCoordinates(rl$faceTextureVCoordinates);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@MethodHook("buildSharedModel")
|
||||
@Inject
|
||||
public void rl$buildSharedModel(boolean refTransparencies, Model sharedModel, byte[] transparencyBuffer)
|
||||
{
|
||||
// Animated models are usually a shared Model instance that is global
|
||||
RSModel rsModel = (RSModel) sharedModel;
|
||||
rsModel.setFaceTextureUCoordinates(rl$faceTextureUCoordinates);
|
||||
rsModel.setFaceTextureVCoordinates(rl$faceTextureVCoordinates);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void interpolateFrames(RSFrames frames, int frameId, RSFrames nextFrames, int nextFrameId, int interval,
|
||||
int intervalCount)
|
||||
@@ -277,4 +365,74 @@ public abstract class RSModelMixin implements RSModel
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getSceneId()
|
||||
{
|
||||
return rl$sceneId;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setSceneId(int sceneId)
|
||||
{
|
||||
this.rl$sceneId = sceneId;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getBufferOffset()
|
||||
{
|
||||
return rl$bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setBufferOffset(int bufferOffset)
|
||||
{
|
||||
rl$bufferOffset = bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getUvBufferOffset()
|
||||
{
|
||||
return rl$uvBufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setUvBufferOffset(int bufferOffset)
|
||||
{
|
||||
rl$uvBufferOffset = bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public float[][] getFaceTextureUCoordinates()
|
||||
{
|
||||
return rl$faceTextureUCoordinates;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setFaceTextureUCoordinates(float[][] faceTextureUCoordinates)
|
||||
{
|
||||
this.rl$faceTextureUCoordinates = faceTextureUCoordinates;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public float[][] getFaceTextureVCoordinates()
|
||||
{
|
||||
return rl$faceTextureVCoordinates;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setFaceTextureVCoordinates(float[][] faceTextureVCoordinates)
|
||||
{
|
||||
this.rl$faceTextureVCoordinates = faceTextureVCoordinates;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,13 @@ package net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Renderable;
|
||||
import net.runelite.api.SceneTileModel;
|
||||
import net.runelite.api.SceneTilePaint;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.hooks.DrawCallbacks;
|
||||
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;
|
||||
@@ -37,26 +41,45 @@ import net.runelite.rs.api.RSDecorativeObject;
|
||||
import net.runelite.rs.api.RSGroundObject;
|
||||
import net.runelite.rs.api.RSItemLayer;
|
||||
import net.runelite.rs.api.RSScene;
|
||||
import net.runelite.rs.api.RSSceneTileModel;
|
||||
import net.runelite.rs.api.RSTile;
|
||||
import net.runelite.rs.api.RSWallObject;
|
||||
|
||||
@Mixin(RSScene.class)
|
||||
public abstract class RSSceneMixin implements RSScene
|
||||
{
|
||||
private static final int MAX_DISTANCE = 25;
|
||||
private static final int DEFAULT_DISTANCE = 25;
|
||||
private static final int MAX_DISTANCE = 90;
|
||||
|
||||
private static final int PITCH_LOWER_LIMIT = 128;
|
||||
private static final int PITCH_UPPER_LIMIT = 383;
|
||||
|
||||
private static final int MAX_TARGET_DISTANCE = 45;
|
||||
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
static RSClient client;
|
||||
|
||||
@Shadow("pitchRelaxEnabled")
|
||||
private static boolean pitchRelaxEnabled;
|
||||
|
||||
@Inject
|
||||
private static int[] tmpX = new int[6];
|
||||
|
||||
@Inject
|
||||
private static int[] tmpY = new int[6];
|
||||
|
||||
@Inject
|
||||
private static int rl$drawDistance;
|
||||
|
||||
@Replace("drawScene")
|
||||
void rl$drawScene(int cameraX, int cameraY, int cameraZ, int cameraPitch, int cameraYaw, int plane)
|
||||
{
|
||||
final DrawCallbacks drawCallbacks = client.getDrawCallbacks();
|
||||
if (drawCallbacks != null)
|
||||
{
|
||||
drawCallbacks.drawScene(cameraX, cameraY, cameraZ, cameraPitch, cameraYaw, plane);
|
||||
}
|
||||
|
||||
final int maxX = getMaxX();
|
||||
final int maxY = getMaxY();
|
||||
final int maxZ = getMaxZ();
|
||||
@@ -64,7 +87,8 @@ public abstract class RSSceneMixin implements RSScene
|
||||
final int minLevel = getMinLevel();
|
||||
|
||||
final RSTile[][][] tiles = getTiles();
|
||||
final int distance = MAX_DISTANCE;
|
||||
final boolean isGpu = client.isGpu();
|
||||
final int distance = isGpu ? rl$drawDistance : DEFAULT_DISTANCE;
|
||||
|
||||
if (cameraX < 0)
|
||||
{
|
||||
@@ -168,7 +192,8 @@ public abstract class RSSceneMixin implements RSScene
|
||||
{
|
||||
if (tile.getPhysicalLevel() <= plane
|
||||
&& (renderArea[x - screenCenterX + MAX_DISTANCE][y - screenCenterZ + MAX_DISTANCE]
|
||||
|| tileHeights[z][x][y] - cameraY >= 2000))
|
||||
|| tileHeights[z][x][y] - cameraY >= 2000
|
||||
|| isGpu))
|
||||
{
|
||||
tile.setDraw(true);
|
||||
tile.setVisible(true);
|
||||
@@ -402,13 +427,271 @@ public abstract class RSSceneMixin implements RSScene
|
||||
@Replace("drawTileUnderlay")
|
||||
public void rl$drawTileUnderlay(SceneTilePaint tile, int z, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y)
|
||||
{
|
||||
if (!client.isGpu())
|
||||
{
|
||||
try
|
||||
{
|
||||
rs$drawTileUnderlay(tile, z, pitchSin, pitchCos, yawSin, yawCos, x, y);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
client.getLogger().warn("error during tile underlay rendering", ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final DrawCallbacks drawCallbacks = client.getDrawCallbacks();
|
||||
|
||||
if (drawCallbacks == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
rs$drawTileUnderlay(tile, z, pitchSin, pitchCos, yawSin, yawCos, x, y);
|
||||
final int[][][] tileHeights = getTileHeights();
|
||||
|
||||
final int cameraX2 = client.getCameraX2();
|
||||
final int cameraY2 = client.getCameraY2();
|
||||
final int cameraZ2 = client.getCameraZ2();
|
||||
|
||||
final int zoom = client.get3dZoom();
|
||||
final int centerX = client.getCenterX();
|
||||
final int centerY = client.getCenterY();
|
||||
|
||||
final int mouseX2 = client.getMouseX2();
|
||||
final int mouseY2 = client.getMouseY2();
|
||||
|
||||
final boolean checkClick = client.isCheckClick();
|
||||
|
||||
int var9;
|
||||
int var10 = var9 = (x << 7) - cameraX2;
|
||||
int var11;
|
||||
int var12 = var11 = (y << 7) - cameraZ2;
|
||||
int var13;
|
||||
int var14 = var13 = var10 + 128;
|
||||
int var15;
|
||||
int var16 = var15 = var12 + 128;
|
||||
int var17 = tileHeights[z][x][y] - cameraY2;
|
||||
int var18 = tileHeights[z][x + 1][y] - cameraY2;
|
||||
int var19 = tileHeights[z][x + 1][y + 1] - cameraY2;
|
||||
int var20 = tileHeights[z][x][y + 1] - cameraY2;
|
||||
int var21 = var10 * yawCos + yawSin * var12 >> 16;
|
||||
var12 = var12 * yawCos - yawSin * var10 >> 16;
|
||||
var10 = var21;
|
||||
var21 = var17 * pitchCos - pitchSin * var12 >> 16;
|
||||
var12 = pitchSin * var17 + var12 * pitchCos >> 16;
|
||||
var17 = var21;
|
||||
if (var12 >= 50)
|
||||
{
|
||||
var21 = var14 * yawCos + yawSin * var11 >> 16;
|
||||
var11 = var11 * yawCos - yawSin * var14 >> 16;
|
||||
var14 = var21;
|
||||
var21 = var18 * pitchCos - pitchSin * var11 >> 16;
|
||||
var11 = pitchSin * var18 + var11 * pitchCos >> 16;
|
||||
var18 = var21;
|
||||
if (var11 >= 50)
|
||||
{
|
||||
var21 = var13 * yawCos + yawSin * var16 >> 16;
|
||||
var16 = var16 * yawCos - yawSin * var13 >> 16;
|
||||
var13 = var21;
|
||||
var21 = var19 * pitchCos - pitchSin * var16 >> 16;
|
||||
var16 = pitchSin * var19 + var16 * pitchCos >> 16;
|
||||
var19 = var21;
|
||||
if (var16 >= 50)
|
||||
{
|
||||
var21 = var9 * yawCos + yawSin * var15 >> 16;
|
||||
var15 = var15 * yawCos - yawSin * var9 >> 16;
|
||||
var9 = var21;
|
||||
var21 = var20 * pitchCos - pitchSin * var15 >> 16;
|
||||
var15 = pitchSin * var20 + var15 * pitchCos >> 16;
|
||||
if (var15 >= 50)
|
||||
{
|
||||
int dy = var10 * zoom / var12 + centerX;
|
||||
int dx = var17 * zoom / var12 + centerY;
|
||||
int cy = var14 * zoom / var11 + centerX;
|
||||
int cx = var18 * zoom / var11 + centerY;
|
||||
int ay = var13 * zoom / var16 + centerX;
|
||||
int ax = var19 * zoom / var16 + centerY;
|
||||
int by = var9 * zoom / var15 + centerX;
|
||||
int bx = var21 * zoom / var15 + centerY;
|
||||
|
||||
drawCallbacks.drawScenePaint(0, pitchSin, pitchCos, yawSin, yawCos,
|
||||
-cameraX2, -cameraY2, -cameraZ2,
|
||||
tile, z, x, y,
|
||||
zoom, centerX, centerY);
|
||||
|
||||
if ((ay - by) * (cx - bx) - (ax - bx) * (cy - by) > 0)
|
||||
{
|
||||
if (checkClick && client.containsBounds(mouseX2, mouseY2, ax, bx, cx, ay, by, cy))
|
||||
{
|
||||
setTargetTile(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
if ((dy - cy) * (bx - cx) - (dx - cx) * (by - cy) > 0)
|
||||
{
|
||||
if (checkClick && client.containsBounds(mouseX2, mouseY2, dx, cx, bx, dy, cy, by))
|
||||
{
|
||||
setTargetTile(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
client.getLogger().warn("error during tile underlay rendering", ex);
|
||||
client.getLogger().warn("error during underlay rendering", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Copy("drawTileOverlay")
|
||||
abstract public void rs$drawTileOverlay(SceneTileModel tile, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y);
|
||||
|
||||
@Replace("drawTileOverlay")
|
||||
public void rl$drawTileOverlay(SceneTileModel tile, int pitchSin, int pitchCos, int yawSin, int yawCos, int tileX, int tileY)
|
||||
{
|
||||
if (!client.isGpu())
|
||||
{
|
||||
rs$drawTileOverlay(tile, pitchSin, pitchCos, yawSin, yawCos, tileX, tileY);
|
||||
return;
|
||||
}
|
||||
|
||||
final DrawCallbacks drawCallbacks = client.getDrawCallbacks();
|
||||
|
||||
if (drawCallbacks == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final int cameraX2 = client.getCameraX2();
|
||||
final int cameraY2 = client.getCameraY2();
|
||||
final int cameraZ2 = client.getCameraZ2();
|
||||
final int zoom = client.get3dZoom();
|
||||
final int centerX = client.getCenterX();
|
||||
final int centerY = client.getCenterY();
|
||||
|
||||
drawCallbacks.drawSceneModel(0, pitchSin, pitchCos, yawSin, yawCos, -cameraX2, -cameraY2, -cameraZ2,
|
||||
tile, client.getPlane(), tileX, tileY,
|
||||
zoom, centerX, centerY);
|
||||
|
||||
final boolean checkClick = client.isCheckClick();
|
||||
if (!checkClick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RSSceneTileModel sceneTileModel = (RSSceneTileModel) tile;
|
||||
|
||||
final int[] faceX = sceneTileModel.getFaceX();
|
||||
final int[] faceY = sceneTileModel.getFaceY();
|
||||
final int[] faceZ = sceneTileModel.getFaceZ();
|
||||
|
||||
final int[] vertexX = sceneTileModel.getVertexX();
|
||||
final int[] vertexY = sceneTileModel.getVertexY();
|
||||
final int[] vertexZ = sceneTileModel.getVertexZ();
|
||||
|
||||
final int vertexCount = vertexX.length;
|
||||
final int faceCount = faceX.length;
|
||||
|
||||
final int mouseX2 = client.getMouseX2();
|
||||
final int mouseY2 = client.getMouseY2();
|
||||
|
||||
for (int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
int vx = vertexX[i] - cameraX2;
|
||||
int vy = vertexY[i] - cameraY2;
|
||||
int vz = vertexZ[i] - cameraZ2;
|
||||
|
||||
int rotA = vz * yawSin + vx * yawCos >> 16;
|
||||
int rotB = vz * yawCos - vx * yawSin >> 16;
|
||||
|
||||
int var13 = vy * pitchCos - rotB * pitchSin >> 16;
|
||||
int var12 = vy * pitchSin + rotB * pitchCos >> 16;
|
||||
if (var12 < 50)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int ax = rotA * zoom / var12 + centerX;
|
||||
int ay = var13 * zoom / var12 + centerY;
|
||||
|
||||
tmpX[i] = ax;
|
||||
tmpY[i] = ay;
|
||||
}
|
||||
|
||||
for (int i = 0; i < faceCount; ++i)
|
||||
{
|
||||
int va = faceX[i];
|
||||
int vb = faceY[i];
|
||||
int vc = faceZ[i];
|
||||
|
||||
int x1 = tmpX[va];
|
||||
int x2 = tmpX[vb];
|
||||
int x3 = tmpX[vc];
|
||||
|
||||
int y1 = tmpY[va];
|
||||
int y2 = tmpY[vb];
|
||||
int y3 = tmpY[vc];
|
||||
|
||||
if ((x1 - x2) * (y3 - y2) - (y1 - y2) * (x3 - x2) > 0)
|
||||
{
|
||||
if (client.containsBounds(mouseX2, mouseY2, y1, y2, y3, x1, x2, x3))
|
||||
{
|
||||
setTargetTile(tileX, tileY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
client.getLogger().warn("error during overlay rendering", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getDrawDistance()
|
||||
{
|
||||
return rl$drawDistance;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setDrawDistance(int drawDistance)
|
||||
{
|
||||
rl$drawDistance = drawDistance;
|
||||
}
|
||||
|
||||
@Inject
|
||||
static void setTargetTile(int targetX, int targetY)
|
||||
{
|
||||
final LocalPoint current = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
// Limit walk distance - https://math.stackexchange.com/a/85582
|
||||
final int a = current.getSceneX();
|
||||
final int b = current.getSceneY();
|
||||
final int c = targetX;
|
||||
final int d = targetY;
|
||||
|
||||
final int r = MAX_TARGET_DISTANCE;
|
||||
final int t = (int) Math.hypot(a - c, b - d) - r;
|
||||
int x = targetX;
|
||||
int y = targetY;
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
x = (r * c + t * a) / (r + t);
|
||||
y = (r * d + t * b) / (r + t);
|
||||
}
|
||||
|
||||
client.setSelectedSceneTileX(x);
|
||||
client.setSelectedSceneTileY(y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.rs.api.RSSceneTileModel;
|
||||
|
||||
@Mixin(RSSceneTileModel.class)
|
||||
public abstract class RSSceneTileModelMixin implements RSSceneTileModel
|
||||
{
|
||||
@Inject
|
||||
private int rl$modelBufferOffset;
|
||||
|
||||
@Inject
|
||||
private int rl$modelUvBufferOffset;
|
||||
|
||||
@Inject
|
||||
private int rl$modelBufferLen;
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getBufferOffset()
|
||||
{
|
||||
return rl$modelBufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setBufferOffset(int bufferOffset)
|
||||
{
|
||||
rl$modelBufferOffset = bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getUvBufferOffset()
|
||||
{
|
||||
return rl$modelUvBufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setUvBufferOffset(int bufferOffset)
|
||||
{
|
||||
rl$modelUvBufferOffset = bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getBufferLen()
|
||||
{
|
||||
return rl$modelBufferLen;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setBufferLen(int bufferLen)
|
||||
{
|
||||
rl$modelBufferLen = bufferLen;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.rs.api.RSSceneTilePaint;
|
||||
|
||||
@Mixin(RSSceneTilePaint.class)
|
||||
public abstract class RSSceneTilePaintMixin implements RSSceneTilePaint
|
||||
{
|
||||
@Inject
|
||||
private int rl$paintModelBufferOffset;
|
||||
|
||||
@Inject
|
||||
private int rl$paintModelUvBufferOffset;
|
||||
|
||||
@Inject
|
||||
private int rl$paintModelBufferLen;
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getBufferOffset()
|
||||
{
|
||||
return rl$paintModelBufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setBufferOffset(int bufferOffset)
|
||||
{
|
||||
rl$paintModelBufferOffset = bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getUvBufferOffset()
|
||||
{
|
||||
return rl$paintModelUvBufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setUvBufferOffset(int bufferOffset)
|
||||
{
|
||||
rl$paintModelUvBufferOffset = bufferOffset;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getBufferLen()
|
||||
{
|
||||
return rl$paintModelBufferLen;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setBufferLen(int bufferLen)
|
||||
{
|
||||
rl$paintModelBufferLen = bufferLen;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 net.runelite.mixins;
|
||||
|
||||
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.RSTexture;
|
||||
|
||||
@Mixin(RSTexture.class)
|
||||
public abstract class RSTextureMixin implements RSTexture
|
||||
{
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private float rl$u;
|
||||
|
||||
@Inject
|
||||
private float rl$v;
|
||||
|
||||
@Copy("animate")
|
||||
public abstract void rs$animate(int diff);
|
||||
|
||||
@Replace("animate")
|
||||
public void rl$animate(int diff)
|
||||
{
|
||||
// The client animates textures by cycling the backing pixels of the texture each fram
|
||||
// based on how long it was since the last tick. On GPU we let the plugin manage this
|
||||
// which will calculate uvs instead.
|
||||
if (!client.isGpu())
|
||||
{
|
||||
rs$animate(diff);
|
||||
return;
|
||||
}
|
||||
|
||||
client.getDrawCallbacks().animate(this, diff);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public float getU()
|
||||
{
|
||||
return rl$u;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setU(float u)
|
||||
{
|
||||
this.rl$u = u;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public float getV()
|
||||
{
|
||||
return rl$v;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setV(float v)
|
||||
{
|
||||
this.rl$v = v;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.IndexDataBase;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.MethodHook;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
@@ -37,9 +38,20 @@ public abstract class RSTextureProviderMixin implements RSTextureProvider
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@MethodHook(value = "<init>", end = true)
|
||||
@Inject
|
||||
public void rl$init(IndexDataBase indexTextures, IndexDataBase indexSprites, int maxSize, double brightness, int width)
|
||||
{
|
||||
// the client's max size is 20, however there are many scenes with >20 textures,
|
||||
// which causes continuous alloc/free of textures with the gl. There are
|
||||
// only ~57 textures in total.
|
||||
setMaxSize(64);
|
||||
setSize(64);
|
||||
}
|
||||
|
||||
@MethodHook(value = "checkTextures", end = true)
|
||||
public void checkTextures(int var1)
|
||||
@Inject
|
||||
public void checkTextures(int diff)
|
||||
{
|
||||
client.getCallbacks().drawAboveOverheads();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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 net.runelite.mixins;
|
||||
|
||||
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;
|
||||
|
||||
@Mixin(RSClient.class)
|
||||
public abstract class Rasterizer2DMixin implements RSClient
|
||||
{
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private static void drawAlpha(int[] pixels, int index, int value, int color, int alpha)
|
||||
{
|
||||
if (!client.isGpu() || pixels != client.getBufferProvider().getPixels())
|
||||
{
|
||||
pixels[index] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int prevColor = pixels[index];
|
||||
|
||||
if ((prevColor & 0xFF000000) == 0 || alpha == 255)
|
||||
{
|
||||
// No transparency, so we can cheat to save CPU resources
|
||||
pixels[index] = (color & 0xFFFFFF) | (alpha << 24);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((prevColor & 0xFF000000) == 0xFF000000)
|
||||
{
|
||||
// When the background is opaque, the result will also be opaque,
|
||||
// so we can simply use the value calculated by Jagex.
|
||||
pixels[index] = value | 0xFF000000;
|
||||
return;
|
||||
}
|
||||
|
||||
int prevAlpha = (prevColor >>> 24) * (255 - alpha) >>> 8;
|
||||
int finalAlpha = alpha + prevAlpha;
|
||||
|
||||
// Scale alphas so (relativeAlpha >>> 8) is approximately equal to (alpha / finalAlpha).
|
||||
// Avoiding extra divisions increase performance by quite a bit.
|
||||
// And with divisions we get a problems if dividing a number where
|
||||
// the last bit is 1 (as it will become negative).
|
||||
int relativeAlpha1 = (alpha << 8) / finalAlpha;
|
||||
int relativeAlpha2 = (prevAlpha << 8) / finalAlpha;
|
||||
|
||||
// Red and blue are calculated at the same time to save CPU cycles
|
||||
int finalColor =
|
||||
(((color & 0xFF00FF) * relativeAlpha1 + (prevColor & 0xFF00FF) * relativeAlpha2 & 0xFF00FF00) |
|
||||
((color & 0x00FF00) * relativeAlpha1 + (prevColor & 0x00FF00) * relativeAlpha2 & 0x00FF0000)) >>> 8;
|
||||
|
||||
pixels[index] = finalColor | (finalAlpha << 24);
|
||||
}
|
||||
|
||||
@Copy("drawGradientAlpha")
|
||||
private static void rs$raster2d6(int var0, int var1, int var2, int var3, int var4, int var5, int var6, int var7)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Replace("drawGradientAlpha")
|
||||
private static void rl$drawGradientAlpha(int var0, int var1, int var2, int var3, int var4, int var5, int var6, int var7)
|
||||
{
|
||||
final int width = client.getGraphicsPixelsWidth();
|
||||
final int startX = client.getStartX();
|
||||
final int startY = client.getStartY();
|
||||
final int endX = client.getEndX();
|
||||
final int endY = client.getEndY();
|
||||
final int[] pixels = client.getGraphicsPixels();
|
||||
|
||||
if (!client.isGpu())
|
||||
{
|
||||
rs$raster2d6(var0, var1, var2, var3, var4, var5, var6, var7);
|
||||
return;
|
||||
}
|
||||
|
||||
if (var2 > 0 && var3 > 0)
|
||||
{
|
||||
int var8 = 0;
|
||||
int var9 = 65536 / var3;
|
||||
if (var0 < startX)
|
||||
{
|
||||
var2 -= startX - var0;
|
||||
var0 = startX;
|
||||
}
|
||||
|
||||
if (var1 < startY)
|
||||
{
|
||||
var8 += (startY - var1) * var9;
|
||||
var3 -= startY - var1;
|
||||
var1 = startY;
|
||||
}
|
||||
|
||||
if (var0 + var2 > endX)
|
||||
{
|
||||
var2 = endX - var0;
|
||||
}
|
||||
|
||||
if (var3 + var1 > endY)
|
||||
{
|
||||
var3 = endY - var1;
|
||||
}
|
||||
|
||||
int var10 = width - var2;
|
||||
int var11 = var0 + width * var1;
|
||||
|
||||
for (int var12 = -var3; var12 < 0; ++var12)
|
||||
{
|
||||
int var13 = 65536 - var8 >> 8;
|
||||
int var14 = var8 >> 8;
|
||||
int var15 = (var13 * var6 + var14 * var7 & 65280) >>> 8;
|
||||
if (var15 == 0)
|
||||
{
|
||||
var11 += width;
|
||||
var8 += var9;
|
||||
}
|
||||
else
|
||||
{
|
||||
int var16 = (var14 * (var5 & 16711935) + var13 * (var4 & 16711935) & -16711936) + (var14 * (var5 & 65280) + var13 * (var4 & 65280) & 16711680) >>> 8;
|
||||
|
||||
for (int var19 = -var2; var19 < 0; ++var19)
|
||||
{
|
||||
drawAlpha(pixels, var11++, 0, var16, var15);
|
||||
}
|
||||
|
||||
var11 += var10;
|
||||
var8 += var9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Copy("raster2d7")
|
||||
public static void rs$raster2d7(int var0, int var1, int var2, int var3, int var4, int var5, byte[] var6, int var7)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Replace("raster2d7")
|
||||
public static void rl$raster2d7(int var0, int var1, int var2, int var3, int var4, int var5, byte[] var6, int var7)
|
||||
{
|
||||
final int width = client.getGraphicsPixelsWidth();
|
||||
final int height = client.getGraphicsPixelsHeight();
|
||||
final int[] pixels = client.getGraphicsPixels();
|
||||
|
||||
if (!client.isGpu())
|
||||
{
|
||||
rs$raster2d7(var0, var1, var2, var3, var4, var5, var6, var7);
|
||||
return;
|
||||
}
|
||||
|
||||
if (var0 + var2 >= 0 && var3 + var1 >= 0)
|
||||
{
|
||||
if (var0 < width && var1 < height)
|
||||
{
|
||||
int var8 = 0;
|
||||
int var9 = 0;
|
||||
if (var0 < 0)
|
||||
{
|
||||
var8 -= var0;
|
||||
var2 += var0;
|
||||
}
|
||||
|
||||
if (var1 < 0)
|
||||
{
|
||||
var9 -= var1;
|
||||
var3 += var1;
|
||||
}
|
||||
|
||||
if (var0 + var2 > width)
|
||||
{
|
||||
var2 = width - var0;
|
||||
}
|
||||
|
||||
if (var3 + var1 > height)
|
||||
{
|
||||
var3 = height - var1;
|
||||
}
|
||||
|
||||
int var10 = var6.length / var7;
|
||||
int var11 = width - var2;
|
||||
int var12 = var4 >>> 24;
|
||||
int var13 = var5 >>> 24;
|
||||
int var14;
|
||||
int var15;
|
||||
int var16;
|
||||
int var17;
|
||||
int var18;
|
||||
if (var12 == 255 && var13 == 255)
|
||||
{
|
||||
var14 = var0 + var8 + (var9 + var1) * width;
|
||||
|
||||
for (var15 = var9 + var1; var15 < var3 + var9 + var1; ++var15)
|
||||
{
|
||||
for (var16 = var0 + var8; var16 < var0 + var8 + var2; ++var16)
|
||||
{
|
||||
var17 = (var15 - var1) % var10;
|
||||
var18 = (var16 - var0) % var7;
|
||||
if (var6[var18 + var17 * var7] != 0)
|
||||
{
|
||||
pixels[var14++] = var5;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixels[var14++] = var4;
|
||||
}
|
||||
}
|
||||
|
||||
var14 += var11;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var14 = var0 + var8 + (var9 + var1) * width;
|
||||
|
||||
for (var15 = var9 + var1; var15 < var3 + var9 + var1; ++var15)
|
||||
{
|
||||
for (var16 = var0 + var8; var16 < var0 + var8 + var2; ++var16)
|
||||
{
|
||||
var17 = (var15 - var1) % var10;
|
||||
var18 = (var16 - var0) % var7;
|
||||
int var19 = var4;
|
||||
if (var6[var18 + var17 * var7] != 0)
|
||||
{
|
||||
var19 = var5;
|
||||
}
|
||||
|
||||
int var20 = var19 >>> 24;
|
||||
drawAlpha(pixels, var14++, 0, var19, var20);
|
||||
}
|
||||
|
||||
var14 += var11;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user