summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/TCompressor.java
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 22:33:32 -0800
committerFuwn <[email protected]>2026-02-12 22:33:32 -0800
commitc7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch)
treedf9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/TCompressor.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/TCompressor.java')
-rw-r--r--NET/worlds/scape/TCompressor.java465
1 files changed, 465 insertions, 0 deletions
diff --git a/NET/worlds/scape/TCompressor.java b/NET/worlds/scape/TCompressor.java
new file mode 100644
index 0000000..d9411dd
--- /dev/null
+++ b/NET/worlds/scape/TCompressor.java
@@ -0,0 +1,465 @@
+package NET.worlds.scape;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class TCompressor {
+ private static final int CMAP_MAXPOSCOMP = 128;
+ private static final int CMAP_DEFAULTAXIS = 0;
+ private static final int CMAP_XUNITARY = 32;
+ private static final int CMAP_YUNITARY = 64;
+ private static final int CMAP_ZUNITARY = 96;
+ private static final int CMAP_ROTATION = 16;
+ private static final int CMAP_ROTSIGN1 = 8;
+ private static final int CMAP_ROTSIGN2 = 4;
+ private static final int CMAP_SCALE = 2;
+ private static final int CMAP_UNIFORMSCALE = 1;
+ private static final int MODE_SENDCMAP = 8388608;
+ private static final int MODE_SENDZ = 4194304;
+ private static final int MODE_MAXPOSCOMP = 128;
+ private static final int MODE_SENDROTAXIS = 96;
+ private static final int MODE_SENDROTATION = 16;
+ private static final int MODE_SENDSCALE = 2;
+ public static final int USER_SEND_POSITION = 32768;
+ public static final int USER_SEND_ROTATION = 16384;
+ public static final int USER_SEND_SCALE = 8192;
+ public static final int USER_SEND_ALL = 57344;
+ private static final int LOW21BITSMASK = 2097151;
+ private static final int LOW18BITSMASK = 262143;
+ private static final int LOW12BITSMASK = 4095;
+ private static final int LOW10BITSMASK = 1023;
+ private static final int LOW8BITSMASK = 255;
+ private static final int BIT20 = 1048576;
+ private static final double SCFACT = 16.0;
+ private static final double SCOFFSET = 121.6;
+ static int wroteBytes = 0;
+ public static boolean dontSend = false;
+
+ public static void compress(WObject w, Point3Temp defPos, Point3Temp defRAxis, float defRotation, Point3Temp defScale, int inputModes, DataOutputStream ds) throws IOException {
+ Point3Temp pos = w.getPosition();
+ Point3Temp rAxis = Point3Temp.make();
+ float rotation = w.getSpin(rAxis);
+ Point3Temp scale = w.getScale();
+ if (dontSend) {
+ System.err.println("DONTSEND is TRUE on COMPRESS CALL");
+ } else {
+ int mode = inputModes;
+ if ((inputModes & 32768) != 0) {
+ if (pos.x >= 0.0F && pos.x <= 4095.0 && pos.y >= 0.0F && pos.y <= 4095.0 && (pos.z >= 0.0F && pos.z <= 255.0 || pos.z == defPos.z)) {
+ mode = inputModes | 128;
+ }
+
+ if (pos.z != defPos.z) {
+ mode |= 4194304;
+ }
+ }
+
+ int outaxis1 = 0;
+ int outaxis2 = 0;
+ if ((mode & 16384) != 0 && !rAxis.sameValue(defRAxis)) {
+ int axisFlag = 0;
+ float maxAxis = rAxis.x;
+ int var24 = 32;
+ if (Math.abs(rAxis.y) > Math.abs(maxAxis)) {
+ maxAxis = rAxis.y;
+ var24 = 64;
+ }
+
+ if (Math.abs(rAxis.z) > Math.abs(maxAxis)) {
+ maxAxis = rAxis.z;
+ var24 = 96;
+ }
+
+ rAxis.x /= maxAxis;
+ rAxis.y /= maxAxis;
+ rAxis.z /= maxAxis;
+ mode |= var24;
+ if (maxAxis < 0.0F) {
+ rotation *= -1.0F;
+ }
+
+ switch (var24) {
+ case 32:
+ if (rAxis.y < 0.0F) {
+ mode |= 8;
+ }
+
+ if (rAxis.z < 0.0F) {
+ mode |= 4;
+ }
+
+ outaxis1 = Math.round(Math.abs(255.0F * rAxis.y));
+ outaxis2 = Math.round(Math.abs(255.0F * rAxis.z));
+ break;
+ case 64:
+ if (rAxis.x < 0.0F) {
+ mode |= 8;
+ }
+
+ if (rAxis.z < 0.0F) {
+ mode |= 4;
+ }
+
+ outaxis1 = Math.round(Math.abs(255.0F * rAxis.x));
+ outaxis2 = Math.round(Math.abs(255.0F * rAxis.z));
+ break;
+ case 96:
+ if (rAxis.x < 0.0F) {
+ mode |= 8;
+ }
+
+ if (rAxis.y < 0.0F) {
+ mode |= 4;
+ }
+
+ outaxis1 = Math.round(Math.abs(255.0F * rAxis.x));
+ outaxis2 = Math.round(Math.abs(255.0F * rAxis.y));
+ }
+
+ if (outaxis1 == 0 && outaxis2 == 0 && maxAxis < 0.0F) {
+ mode |= 8;
+ mode |= 4;
+ }
+
+ while (rotation >= 360.0F) {
+ rotation -= 360.0F;
+ }
+
+ while (rotation < 0.0F) {
+ rotation += 360.0F;
+ }
+
+ if (rotation != defRotation) {
+ mode |= 8388608;
+ mode |= 16;
+ }
+ }
+
+ if ((mode & 8192) != 0 && !scale.sameValue(defScale)) {
+ mode |= 8388608;
+ mode |= 2;
+ if (scale.x == scale.y && scale.x == scale.z) {
+ mode |= 1;
+ }
+ }
+
+ if ((mode & 8388608) != 0) {
+ ds.writeByte(mode & 0xFF);
+ wroteBytes++;
+ }
+
+ if ((mode & 32768) != 0) {
+ if ((mode & 128) != 0) {
+ maxCompressXY(pos.x, pos.y, ds);
+ if ((mode & 4194304) != 0 || (mode & 8388608) != 0) {
+ short iz = (short)Math.round(pos.z);
+ int outbyte = iz & 255;
+ ds.writeByte(outbyte);
+ wroteBytes++;
+ }
+ } else {
+ minCompressXYZ(pos.x, pos.y, pos.z, ds);
+ }
+ }
+
+ if ((mode & 96) != 0) {
+ ds.writeByte(outaxis1);
+ ds.writeByte(outaxis2);
+ wroteBytes += 2;
+ }
+
+ if ((mode & 16) != 0) {
+ int outbyte = (int)Math.round(256.0 * (rotation / 360.0));
+ ds.writeByte(outbyte);
+ wroteBytes++;
+ }
+
+ if ((mode & 2) != 0) {
+ double y = 16.0 * Math.log(scale.x / defScale.x) + 121.6;
+ if (y < 0.0) {
+ y = 0.0;
+ }
+
+ if (y > 255.0) {
+ y = 255.0;
+ }
+
+ int outbyte = (int)Math.round(y);
+ ds.writeByte(outbyte);
+ wroteBytes++;
+ if ((mode & 1) == 0) {
+ y = 16.0 * Math.log(scale.y / defScale.y) + 121.6;
+ if (y < 0.0) {
+ y = 0.0;
+ }
+
+ if (y > 255.0) {
+ y = 255.0;
+ }
+
+ outbyte = (int)Math.round(y);
+ ds.writeByte(outbyte);
+ wroteBytes++;
+ y = 16.0 * Math.log(scale.z / defScale.z) + 121.6;
+ if (y < 0.0) {
+ y = 0.0;
+ }
+
+ if (y > 255.0) {
+ y = 255.0;
+ }
+
+ outbyte = (int)Math.round(y);
+ ds.writeByte(outbyte);
+ wroteBytes++;
+ }
+ }
+
+ wroteBytes = 0;
+ }
+ }
+
+ private static void maxCompressXY(float x, float y, DataOutputStream ds) throws IOException {
+ short ix = (short)Math.round(x);
+ short iy = (short)Math.round(y);
+ ix = (short)(ix & 4095);
+ iy = (short)(iy & 4095);
+ int posbyte = ix >>> 4;
+ ds.writeByte(posbyte);
+ wroteBytes++;
+ ix = (short)(ix << 4);
+ ix = (short)(ix & 255);
+ posbyte = ix | iy >>> 8;
+ ds.writeByte(posbyte);
+ wroteBytes++;
+ posbyte = iy & 255;
+ ds.writeByte(posbyte);
+ wroteBytes++;
+ }
+
+ private static void minCompressXYZ(float x, float y, float z, DataOutputStream ds) throws IOException {
+ int xval = floatTo21bits(x);
+ int yval = floatTo21bits(y);
+ int zval = floatTo21bits(z);
+ int outbits = xval << 10 | yval >>> 11;
+ ds.writeInt(outbits);
+ wroteBytes += 4;
+ outbits = yval << 21 | zval;
+ ds.writeInt(outbits);
+ wroteBytes += 4;
+ }
+
+ private static int floatTo21bits(float f) {
+ for (int e = 0; e <= 3; e++) {
+ double decimal = Math.pow(10.0, e - 2);
+ float limit = (float)(262144.0 * decimal);
+ float af = Math.abs(f);
+ if (af < limit || e == 3) {
+ int m = (int)Math.round(af / decimal);
+ m &= 262143;
+ m <<= 2;
+ m |= e;
+ if (f < 0.0F) {
+ m |= 1048576;
+ }
+
+ return m;
+ }
+ }
+
+ return 0;
+ }
+
+ public static void decompress(
+ WObject w, Point3Temp defPos, Point3Temp defRAxis, float defRotation, Point3Temp defScale, int inputModes, int len, DataInputStream ds
+ ) throws IOException {
+ Point3Temp pos = w.getPosition();
+ Point3Temp rAxis = Point3Temp.make();
+ float rotation = w.getSpin(rAxis);
+ Point3Temp scale = w.getScale();
+ dontSend = true;
+ if (len == 0) {
+ w.moveTo(defPos);
+ scale.x = defScale.x / scale.x;
+ scale.y = defScale.y / scale.y;
+ scale.z = defScale.z / scale.z;
+ w.scale(scale);
+ dontSend = false;
+ } else if (len == 24) {
+ pos.x = ds.readFloat();
+ pos.y = ds.readFloat();
+ pos.z = ds.readFloat();
+ scale.x = ds.readFloat() / scale.x;
+ scale.y = ds.readFloat() / scale.y;
+ scale.z = ds.readFloat() / scale.z;
+ w.moveTo(pos);
+ w.scale(scale);
+ dontSend = false;
+ } else {
+ int mode;
+ if (len > 4) {
+ mode = inputModes | 8388608;
+ } else {
+ mode = inputModes | 128;
+ }
+
+ if (len == 4) {
+ mode |= 4194304;
+ }
+
+ if ((mode & 8388608) != 0) {
+ int inbyte = ds.readUnsignedByte();
+ mode |= inbyte;
+ mode |= 4194304;
+ }
+
+ if ((mode & 32768) != 0) {
+ if ((mode & 128) != 0) {
+ pos = maxDecompressXY(pos, ds);
+ if ((mode & 4194304) != 0) {
+ int iz = ds.readUnsignedByte();
+ pos.z = iz;
+ }
+ } else {
+ pos = minDecompressXYZ(pos, ds);
+ }
+
+ w.moveTo(pos);
+ }
+
+ if ((mode & 8388608) == 0) {
+ dontSend = false;
+ } else {
+ if ((mode & 16) != 0) {
+ w.spin(rAxis.x, rAxis.y, rAxis.z, -rotation);
+ }
+
+ rAxis.x = defRAxis.x;
+ rAxis.y = defRAxis.y;
+ rAxis.z = defRAxis.z;
+ if ((mode & 96) != 0) {
+ int inaxis1 = ds.readUnsignedByte();
+ int inaxis2 = ds.readUnsignedByte();
+ switch (mode & 96) {
+ case 0:
+ default:
+ break;
+ case 32:
+ rAxis.x = 1.0F;
+ rAxis.y = (float)(inaxis1 / 255.0);
+ rAxis.z = (float)(inaxis2 / 255.0);
+ if ((mode & 8) != 0) {
+ rAxis.y = (float)(rAxis.y * -1.0);
+ }
+
+ if ((mode & 4) != 0) {
+ rAxis.z = (float)(rAxis.z * -1.0);
+ }
+
+ if (rAxis.y == 0.0F && rAxis.z == 0.0F && (mode & 8) != 0 && (mode & 4) != 0) {
+ rAxis.x = -1.0F;
+ }
+ break;
+ case 64:
+ rAxis.y = 1.0F;
+ rAxis.x = (float)(inaxis1 / 255.0);
+ rAxis.z = (float)(inaxis2 / 255.0);
+ if ((mode & 8) != 0) {
+ rAxis.x = (float)(rAxis.x * -1.0);
+ }
+
+ if ((mode & 4) != 0) {
+ rAxis.z = (float)(rAxis.z * -1.0);
+ }
+
+ if (rAxis.x == 0.0F && rAxis.z == 0.0F && (mode & 8) != 0 && (mode & 4) != 0) {
+ rAxis.y = -1.0F;
+ }
+ break;
+ case 96:
+ rAxis.z = 1.0F;
+ rAxis.x = (float)(inaxis1 / 255.0);
+ rAxis.y = (float)(inaxis2 / 255.0);
+ if ((mode & 8) != 0) {
+ rAxis.x = (float)(rAxis.x * -1.0);
+ }
+
+ if ((mode & 4) != 0) {
+ rAxis.y = (float)(rAxis.y * -1.0);
+ }
+
+ if (rAxis.x == 0.0F && rAxis.y == 0.0F && (mode & 8) != 0 && (mode & 4) != 0) {
+ rAxis.z = -1.0F;
+ }
+ }
+ }
+
+ if ((mode & 16) != 0) {
+ int inbyte = ds.readUnsignedByte();
+ rotation = (float)(360.0 * (inbyte / 256.0));
+ w.worldSpin(rAxis.x, rAxis.y, rAxis.z, rotation);
+ }
+
+ if ((mode & 2) != 0) {
+ int inbyte = ds.readUnsignedByte();
+ double s = defScale.x * Math.exp((inbyte - 121.6) / 16.0);
+ scale.x = (float)s;
+ if ((mode & 1) != 0) {
+ scale.y = scale.x;
+ scale.z = scale.x;
+ } else {
+ inbyte = ds.readUnsignedByte();
+ s = defScale.y * Math.exp((inbyte - 121.6) / 16.0);
+ scale.y = (float)s;
+ inbyte = ds.readUnsignedByte();
+ s = defScale.z * Math.exp((inbyte - 121.6) / 16.0);
+ scale.z = (float)s;
+ }
+
+ Point3Temp oldScale = w.getScale();
+ scale.x = scale.x / oldScale.x;
+ scale.y = scale.y / oldScale.y;
+ scale.z = scale.z / oldScale.z;
+ w.scale(scale);
+ }
+
+ dontSend = false;
+ }
+ }
+ }
+
+ private static Point3Temp maxDecompressXY(Point3Temp pos, DataInputStream ds) throws IOException {
+ int ix = ds.readUnsignedByte();
+ ix <<= 4;
+ int iy = ds.readUnsignedByte();
+ ix |= iy >>> 4;
+ iy &= 15;
+ iy <<= 8;
+ iy |= ds.readUnsignedByte();
+ pos.x = ix;
+ pos.y = iy;
+ return pos;
+ }
+
+ private static Point3Temp minDecompressXYZ(Point3Temp pos, DataInputStream ds) throws IOException {
+ int i1 = ds.readInt();
+ int i2 = ds.readInt();
+ int tmp = i1 >>> 10;
+ pos.x = floatFrom21bits(tmp);
+ tmp = (i1 & 1023) << 11;
+ tmp |= i2 >>> 21;
+ pos.y = floatFrom21bits(tmp);
+ tmp = i2 & 2097151;
+ pos.z = floatFrom21bits(tmp);
+ return pos;
+ }
+
+ private static float floatFrom21bits(int bits) {
+ int e = bits & 3;
+ int s = (bits & 1048576) << 11 | 1;
+ int m = (bits & -1048577) >>> 2;
+ double d = Math.pow(10.0, e - 2);
+ return (float)(m * d * s);
+ }
+}