Scale the star field background with the UI scale

This commit is contained in:
Alexis King 2022-12-04 01:34:30 -06:00
parent ce8be35cf6
commit 8ec4eb6b6a
4 changed files with 68 additions and 62 deletions

View File

@ -3,7 +3,15 @@ package funorb.graphics;
import funorb.util.ArrayUtil;
import funorb.util.MathUtil;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.Arrays;
import java.util.Hashtable;
public final class Drawing {
public static final int[] SHADES_OF_GRAY = ArrayUtil.build(256, i -> i * 0x010101);
@ -2092,6 +2100,18 @@ public final class Drawing {
}
}
private static final ColorModel RGB_COLOR_MODEL = new DirectColorModel(32, 0xff0000, 0x00ff00, 0x0000ff);
public static BufferedImage createRgbBufferedImage(final int width, final int height, final int[] pixels) {
final DataBufferInt buffer = new DataBufferInt(pixels, pixels.length);
final WritableRaster raster = Raster.createWritableRaster(RGB_COLOR_MODEL.createCompatibleSampleModel(width, height), buffer, null);
return new BufferedImage(RGB_COLOR_MODEL, raster, false, new Hashtable<>());
}
public static Graphics2D createGraphics() {
return createRgbBufferedImage(width, height, screenBuffer).createGraphics();
}
public static int alphaOver(final int color1, final int color2, final int alpha) {
final int rb1 = color1 & 0xff00ff;
final int g1 = color1 & 0x00ff00;

View File

@ -1,9 +1,12 @@
package funorb.graphics;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.PixelGrabber;
public class Sprite {
@ -25,10 +28,10 @@ public class Sprite {
this.pixels = pixels;
}
public Sprite(final int var1, final int var2) {
this.pixels = new int[var1 * var2];
this.width = this.offsetX = var1;
this.height = this.offsetY = var2;
public Sprite(final int width, final int height) {
this.pixels = new int[width * height];
this.width = this.offsetX = width;
this.height = this.offsetY = height;
this.y = 0;
this.x = 0;
}
@ -51,6 +54,15 @@ public class Sprite {
}
}
private Image image;
public final Image asImage() {
if (this.image == null) {
this.image = Drawing.createRgbBufferedImage(this.width, this.height, this.pixels);
}
return this.image;
}
private static void compositeOverTinted(final int[] src, final int srcStride, int srcPos, final int[] dest, final int destStride, int destPos, final int cols, final int rows, final int color) {
final int r1 = (color >> 16) & 255;
final int g1 = (color >> 8) & 255;
@ -1248,6 +1260,14 @@ public class Sprite {
}
}
public final void drawAntialiased(final AffineTransform transform) {
final Graphics2D g = Drawing.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawImage(this.asImage(), transform, null);
}
public final Sprite horizontallyFlipped() {
final Sprite sprite = new Sprite(this.width, this.height);
sprite.offsetX = this.offsetX;

View File

@ -66,6 +66,7 @@ import org.jetbrains.annotations.Nullable;
import javax.sound.sampled.LineUnavailableException;
import java.awt.Canvas;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -81,20 +82,25 @@ import java.util.Random;
import static funorb.shatteredplans.S2CPacket.Type;
public final class ShatteredPlansClient extends JagexApplet {
public static final int ORIGINAL_SCREEN_WIDTH = 640;
public static final int ORIGINAL_SCREEN_HEIGHT = 480;
public static final double UI_SCALE;
public static final int SCREEN_WIDTH;
public static final int SCREEN_HEIGHT;
static {
final String uiScaleStr = System.getProperty("funorb.shatteredplans.client.uiScale", "1.0");
final double uiScale;
try {
uiScale = Double.parseDouble(uiScaleStr);
UI_SCALE = Double.parseDouble(uiScaleStr);
} catch (final NumberFormatException e) {
throw new RuntimeException("non-numeric value for property funorb.shatteredplans.client.uiScale: " + uiScaleStr, e);
}
SCREEN_WIDTH = (int) (640 * uiScale);
SCREEN_HEIGHT = (int) (480 * uiScale);
SCREEN_WIDTH = (int) (ORIGINAL_SCREEN_WIDTH * UI_SCALE);
SCREEN_HEIGHT = (int) (ORIGINAL_SCREEN_HEIGHT * UI_SCALE);
}
public static final AffineTransform ORIGINAL_TO_SCALED_TRANSFORM = AffineTransform.getScaleInstance(UI_SCALE, UI_SCALE);
public static final int[] NUM_PLAYERS_OPTION_VALUES = {2, 3, 4, 5, 6};
public static final int[] GAMEOPT_CHOICES_COUNTS = {5, 7, 4, 5, 2};
public static final Random globalRandom = new Random();
@ -140,7 +146,6 @@ public final class ShatteredPlansClient extends JagexApplet {
public static ClientLobbyRoom unratedLobbyRoom;
private static byte[] playerSeatsFilledBitmap;
private static boolean justRecievedRoomDetailsFromServer;
private static int[] rowBuffer;
private static int _dmgm = SCREEN_HEIGHT;
public static final String[] STAT_NAMES = new String[16];
public static final String[] STAT_DESCS = new String[16];
@ -2450,54 +2455,19 @@ public final class ShatteredPlansClient extends JagexApplet {
}
public static void f423fr() {
final int x = (int) (1600.0D * (1.0D + Math.cos((float) currentTick / 500.0F)));
final int y = (int) (1600.0D * (1.0D - Math.sin((float) currentTick / 500.0F)));
if (renderQuality.antialiasStarfieldBackground && SCREEN_WIDTH == 640 && SCREEN_HEIGHT == 480) {
a034il(x, y, STAR_FIELD);
Drawing.horizontalLine(0, 0, SCREEN_WIDTH, 0);
} else {
Drawing.clear();
STAR_FIELD.c093(-x >> 4, -y >> 4);
}
final double x = 100.0D * (1.0D + Math.cos((float) currentTick / 500.0F));
final double y = 100.0D * (1.0D - Math.sin((float) currentTick / 500.0F));
drawStarField(-x, -y);
}
private static void a034il(int x, int y, final Sprite sprite) {
if (rowBuffer == null || rowBuffer.length != Drawing.width) {
rowBuffer = new int[Drawing.width];
}
final int ySubpixels = y & 15;
y >>= 4;
final int xSubpixels = x & 15;
x >>= 4;
int outPos = 0;
int inPos = sprite.width * y + x;
final int var14 = sprite.width - Drawing.width;
for (int var15 = -Drawing.height; var15 < 0; inPos += var14) {
int var16 = 0;
for (int var17 = Drawing.width - 1; var17 >= 0; --var17) {
final int var6 = sprite.pixels[inPos];
final int var8 = var6 & '\uff00';
final int var7 = var6 & 16711935;
final int var10 = 267390960 & xSubpixels * var7;
final int var11 = xSubpixels * var8 & 1044480;
final int var9 = var11 | var10;
final int i = var16 + var9;
final int i1 = 267390960 & i;
var16 = (var6 << 4) - var9;
final int i2 = i & 1044480;
final int i3 = -16711936 & ySubpixels * i1;
final int i4 = 16711680 & i2 * ySubpixels;
final int i5 = i3 | i4;
Drawing.screenBuffer[outPos] = rowBuffer[var17] + i5 >> 8;
rowBuffer[var17] = (i << 4) - i5;
++outPos;
++inPos;
}
++var15;
public static void drawStarField(final double x, final double y) {
if (renderQuality.antialiasStarfieldBackground || SCREEN_WIDTH != 640 || SCREEN_HEIGHT != 480) {
final AffineTransform transform = new AffineTransform();
transform.translate(x, y);
transform.concatenate(ORIGINAL_TO_SCALED_TRANSFORM);
STAR_FIELD.drawAntialiased(transform);
} else {
STAR_FIELD.c093((int) x, (int) y);
}
}

View File

@ -1,6 +1,5 @@
package funorb.shatteredplans.client.game;
import funorb.graphics.Drawing;
import funorb.graphics.Point;
import funorb.graphics.Rect;
import funorb.graphics.Sprite;
@ -361,12 +360,9 @@ public abstract class AbstractGameView {
}
final void drawBackground() {
Drawing.fillRect(0, 0, Drawing.width, Drawing.height, Drawing.BLACK);
final int var2 = ShatteredPlansClient.STAR_FIELD.width - ShatteredPlansClient.SCREEN_WIDTH;
final int var3 = ShatteredPlansClient.STAR_FIELD.height - ShatteredPlansClient.SCREEN_HEIGHT;
final int var4 = -(((int) this.mapScrollPosnX) * (var2 << 4)) / (this.map.drawingWidth);
final int var6 = -(((int) this.mapScrollPosnY) * (var3 << 4)) / (this.map.drawingHeight);
ShatteredPlansClient.STAR_FIELD.draw(var4 >> 4, var6 >> 4);
final double x = (double) -this.mapScrollPosnX * (ShatteredPlansClient.STAR_FIELD.width - ShatteredPlansClient.ORIGINAL_SCREEN_WIDTH) / this.map.drawingWidth;
final double y = (double) -this.mapScrollPosnY * (ShatteredPlansClient.STAR_FIELD.height - ShatteredPlansClient.ORIGINAL_SCREEN_HEIGHT) / this.map.drawingHeight;
ShatteredPlansClient.drawStarField(x, y);
}
public final void c487() {