mixins: replace drawScene

This is in preparation for extending draw distance.
This commit is contained in:
Adam
2018-11-12 12:20:17 -05:00
parent 49d7c15f24
commit f09a0d7d89
5 changed files with 367 additions and 40 deletions

View File

@@ -24,7 +24,6 @@
*/
package net.runelite.mixins;
import net.runelite.api.Perspective;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
@@ -40,9 +39,6 @@ public abstract class CameraMixin implements RSClient
@Shadow("clientInstance")
static RSClient client;
@Shadow("isDrawingScene")
static boolean isDrawingScene;
@Inject
static boolean pitchRelaxEnabled = false;
@@ -113,27 +109,4 @@ public abstract class CameraMixin implements RSClient
}
lastPitch = pitch;
}
// All of this is to bypass a check in Scene.drawScene
@FieldHook("pitchSin")
@Inject
static void onPitchSinChanged(int idx)
{
if (pitchRelaxEnabled && isDrawingScene)
{
client.setPitchSin(Perspective.SINE[client.getCameraPitch()]);
}
}
@FieldHook("pitchCos")
@Inject
static void onPitchCosChanged(int idx)
{
if (pitchRelaxEnabled && isDrawingScene)
{
client.setPitchCos(Perspective.COSINE[client.getCameraPitch()]);
}
}
}

View File

@@ -24,11 +24,11 @@
*/
package net.runelite.mixins;
import net.runelite.api.Perspective;
import net.runelite.api.Renderable;
import net.runelite.api.SceneTilePaint;
import net.runelite.api.Tile;
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,33 +37,291 @@ 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.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 PITCH_LOWER_LIMIT = 128;
private static final int PITCH_UPPER_LIMIT = 383;
@Shadow("clientInstance")
private static RSClient client;
@Inject
static boolean isDrawingScene;
@Copy("drawScene")
abstract void rs$drawScene(int cameraX, int cameraY, int cameraZ, int cameraPitch, int cameraYaw, int plane);
@Shadow("pitchRelaxEnabled")
private static boolean pitchRelaxEnabled;
@Replace("drawScene")
void rl$drawScene(int cameraX, int cameraY, int cameraZ, int cameraPitch, int cameraYaw, int plane)
{
try
final int maxX = getMaxX();
final int maxY = getMaxY();
final int maxZ = getMaxZ();
final int minLevel = getMinLevel();
final RSTile[][][] tiles = getTiles();
final int distance = MAX_DISTANCE;
if (cameraX < 0)
{
isDrawingScene = true;
rs$drawScene(cameraX, cameraY, cameraZ, cameraPitch, cameraYaw, plane);
client.getCallbacks().drawScene();
cameraX = 0;
}
finally
else if (cameraX >= maxX * Perspective.LOCAL_TILE_SIZE)
{
isDrawingScene = false;
cameraX = maxX * Perspective.LOCAL_TILE_SIZE - 1;
}
if (cameraZ < 0)
{
cameraZ = 0;
}
else if (cameraZ >= maxZ * Perspective.LOCAL_TILE_SIZE)
{
cameraZ = maxZ * Perspective.LOCAL_TILE_SIZE - 1;
}
// we store the uncapped pitch for setting camera angle for the pitch relaxer
// we still have to cap the pitch in order to access the visibility map, though
int realPitch = cameraPitch;
if (cameraPitch < PITCH_LOWER_LIMIT)
{
cameraPitch = PITCH_LOWER_LIMIT;
}
else if (cameraPitch > PITCH_UPPER_LIMIT)
{
cameraPitch = PITCH_UPPER_LIMIT;
}
if (!pitchRelaxEnabled)
{
realPitch = cameraPitch;
}
client.setCycle(client.getCycle() + 1);
client.setPitchSin(Perspective.SINE[realPitch]);
client.setPitchCos(Perspective.COSINE[realPitch]);
client.setYawSin(Perspective.SINE[cameraYaw]);
client.setYawCos(Perspective.COSINE[cameraYaw]);
final int[][][] tileHeights = client.getTileHeights();
boolean[][] renderArea = client.getVisibilityMaps()[(cameraPitch - 128) / 32][cameraYaw / 64];
client.setRenderArea(renderArea);
client.setCameraX2(cameraX);
client.setCameraY2(cameraY);
client.setCameraZ2(cameraZ);
int screenCenterX = cameraX / Perspective.LOCAL_TILE_SIZE;
int screenCenterZ = cameraZ / Perspective.LOCAL_TILE_SIZE;
client.setScreenCenterX(screenCenterX);
client.setScreenCenterZ(screenCenterZ);
client.setScenePlane(plane);
int minTileX = screenCenterX - distance;
if (minTileX < 0)
{
minTileX = 0;
}
int minTileZ = screenCenterZ - distance;
if (minTileZ < 0)
{
minTileZ = 0;
}
int maxTileX = screenCenterX + distance;
if (maxTileX > maxX)
{
maxTileX = maxX;
}
int maxTileZ = screenCenterZ + distance;
if (maxTileZ > maxZ)
{
maxTileZ = maxZ;
}
client.setMinTileX(minTileX);
client.setMinTileZ(minTileZ);
client.setMaxTileX(maxTileX);
client.setMaxTileZ(maxTileZ);
updateOccluders();
client.setTileUpdateCount(0);
for (int z = minLevel; z < maxY; ++z)
{
RSTile[][] planeTiles = tiles[z];
for (int x = minTileX; x < maxTileX; ++x)
{
for (int y = minTileZ; y < maxTileZ; ++y)
{
RSTile tile = planeTiles[x][y];
if (tile != null)
{
if (tile.getPhysicalLevel() <= plane
&& (renderArea[x - screenCenterX + MAX_DISTANCE][y - screenCenterZ + MAX_DISTANCE]
|| tileHeights[z][x][y] - cameraY >= 2000))
{
tile.setDraw(true);
tile.setVisible(true);
tile.setDrawEntities(true);
client.setTileUpdateCount(client.getTileUpdateCount() + 1);
}
else
{
tile.setDraw(false);
tile.setVisible(false);
tile.setWallCullDirection(0);
}
}
}
}
}
for (int z = minLevel; z < maxY; ++z)
{
RSTile[][] planeTiles = tiles[z];
for (int x = -distance; x <= 0; ++x)
{
int var10 = x + screenCenterX;
int var16 = screenCenterX - x;
if (var10 >= minTileX || var16 < maxTileX)
{
for (int y = -distance; y <= 0; ++y)
{
int var13 = y + screenCenterZ;
int var14 = screenCenterZ - y;
if (var10 >= minTileX)
{
if (var13 >= minTileZ)
{
RSTile tile = planeTiles[var10][var13];
if (tile != null && tile.isDraw())
{
draw(tile, true);
}
}
if (var14 < maxTileZ)
{
RSTile tile = planeTiles[var10][var14];
if (tile != null && tile.isDraw())
{
draw(tile, true);
}
}
}
if (var16 < maxTileX)
{
if (var13 >= minTileZ)
{
RSTile tile = planeTiles[var16][var13];
if (tile != null && tile.isDraw())
{
draw(tile, true);
}
}
if (var14 < maxTileZ)
{
RSTile tile = planeTiles[var16][var14];
if (tile != null && tile.isDraw())
{
draw(tile, true);
}
}
}
if (client.getTileUpdateCount() == 0)
{
client.setCheckClick(false);
client.getCallbacks().drawScene();
return;
}
}
}
}
}
for (int z = minLevel; z < maxY; ++z)
{
RSTile[][] planeTiles = tiles[z];
for (int x = -distance; x <= 0; ++x)
{
int var10 = x + screenCenterX;
int var16 = screenCenterX - x;
if (var10 >= minTileX || var16 < maxTileX)
{
for (int y = -distance; y <= 0; ++y)
{
int var13 = y + screenCenterZ;
int var14 = screenCenterZ - y;
if (var10 >= minTileX)
{
if (var13 >= minTileZ)
{
RSTile tile = planeTiles[var10][var13];
if (tile != null && tile.isDraw())
{
draw(tile, false);
}
}
if (var14 < maxTileZ)
{
RSTile tile = planeTiles[var10][var14];
if (tile != null && tile.isDraw())
{
draw(tile, false);
}
}
}
if (var16 < maxTileX)
{
if (var13 >= minTileZ)
{
RSTile tile = planeTiles[var16][var13];
if (tile != null && tile.isDraw())
{
draw(tile, false);
}
}
if (var14 < maxTileZ)
{
RSTile tile = planeTiles[var16][var14];
if (tile != null && tile.isDraw())
{
draw(tile, false);
}
}
}
if (client.getTileUpdateCount() == 0)
{
client.setCheckClick(false);
client.getCallbacks().drawScene();
return;
}
}
}
}
}
client.setCheckClick(false);
client.getCallbacks().drawScene();
}
@Copy("addBoundaryDecoration")

View File

@@ -558,6 +558,12 @@ public interface RSClient extends RSGameEngine, Client
@Import("pitchCos")
void setPitchCos(int v);
@Import("yawSin")
void setYawSin(int v);
@Import("yawCos")
void setYawCos(int v);
@Import("Rasterizer3D_zoom")
int get3dZoom();
@@ -685,4 +691,52 @@ public interface RSClient extends RSGameEngine, Client
@Import("occupiedTilesTick")
int[][] getOccupiedTilesTick();
@Import("cycle")
int getCycle();
@Import("cycle")
void setCycle(int cycle);
@Import("visibilityMaps")
boolean[][][][] getVisibilityMaps();
@Import("renderArea")
void setRenderArea(boolean[][] renderArea);
@Import("cameraX2")
void setCameraX2(int cameraX2);
@Import("cameraY2")
void setCameraY2(int cameraY2);
@Import("cameraZ2")
void setCameraZ2(int cameraZ2);
@Import("screenCenterX")
void setScreenCenterX(int screenCenterX);
@Import("screenCenterZ")
void setScreenCenterZ(int screenCenterZ);
@Import("Scene_plane")
void setScenePlane(int scenePlane);
@Import("minTileX")
void setMinTileX(int i);
@Import("minTileZ")
void setMinTileZ(int i);
@Import("maxTileX")
void setMaxTileX(int i);
@Import("maxTileZ")
void setMaxTileZ(int i);
@Import("tileUpdateCount")
int getTileUpdateCount();
@Import("tileUpdateCount")
void setTileUpdateCount(int tileUpdateCount);
}

View File

@@ -35,8 +35,26 @@ public interface RSScene extends Scene
@Import("tiles")
@Override
Tile[][][] getTiles();
RSTile[][][] getTiles();
@Import("draw")
void draw(Tile tile, boolean var2);
@Import("drawTile")
void drawTile(int[] pixels, int pixelOffset, int width, int z, int x, int y);
@Import("updateOccluders")
void updateOccluders();
@Import("maxX")
int getMaxX();
@Import("maxY")
int getMaxY();
@Import("maxZ")
int getMaxZ();
@Import("minLevel")
int getMinLevel();
}

View File

@@ -73,4 +73,28 @@ public interface RSTile extends Tile
@Import("plane")
@Override
int getPlane();
@Import("physicalLevel")
int getPhysicalLevel();
@Import("draw")
boolean isDraw();
@Import("draw")
void setDraw(boolean draw);
@Import("visible")
boolean isVisible();
@Import("visible")
void setVisible(boolean visible);
@Import("drawEntities")
boolean isDrawEntities();
@Import("drawEntities")
void setDrawEntities(boolean drawEntities);
@Import("wallCullDirection")
void setWallCullDirection(int wallCullDirection);
}