diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/TCompressor.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/TCompressor.java')
| -rw-r--r-- | NET/worlds/scape/TCompressor.java | 465 |
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); + } +} |