mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-03-15 10:21:01 +00:00
begin live server support
This commit is contained in:
parent
0c9ddb476a
commit
e4ae265184
368 changed files with 17756 additions and 7738 deletions
136
relay/BitStreamWriter.ts
Normal file
136
relay/BitStreamWriter.ts
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* Bit-level stream writer, mirroring the V12 engine's BitStream write methods.
|
||||
* Bits are written LSB-first within each byte, matching the read convention.
|
||||
*/
|
||||
export class BitStreamWriter {
|
||||
private data: Uint8Array;
|
||||
private bitNum: number;
|
||||
private maxBitNum: number;
|
||||
|
||||
constructor(maxBytes = 1500) {
|
||||
this.data = new Uint8Array(maxBytes);
|
||||
this.bitNum = 0;
|
||||
this.maxBitNum = maxBytes << 3;
|
||||
}
|
||||
|
||||
getCurPos(): number {
|
||||
return this.bitNum;
|
||||
}
|
||||
|
||||
setCurPos(pos: number): void {
|
||||
this.bitNum = pos;
|
||||
}
|
||||
|
||||
getBytePosition(): number {
|
||||
return (this.bitNum + 7) >> 3;
|
||||
}
|
||||
|
||||
getByteCount(): number {
|
||||
return this.getBytePosition();
|
||||
}
|
||||
|
||||
/** Get a copy of the written bytes. */
|
||||
getBuffer(): Uint8Array {
|
||||
return this.data.slice(0, this.getByteCount());
|
||||
}
|
||||
|
||||
writeFlag(value: boolean): void {
|
||||
if (this.bitNum >= this.maxBitNum) return;
|
||||
if (value) {
|
||||
this.data[this.bitNum >> 3] |= 1 << (this.bitNum & 0x7);
|
||||
} else {
|
||||
this.data[this.bitNum >> 3] &= ~(1 << (this.bitNum & 0x7));
|
||||
}
|
||||
this.bitNum++;
|
||||
}
|
||||
|
||||
/** Write N bits from an unsigned integer, LSB-first. */
|
||||
writeInt(value: number, bitCount: number): void {
|
||||
if (bitCount === 0) return;
|
||||
value = value >>> 0;
|
||||
for (let i = 0; i < bitCount; i++) {
|
||||
if (value & (1 << i)) {
|
||||
this.data[this.bitNum >> 3] |= 1 << (this.bitNum & 0x7);
|
||||
} else {
|
||||
this.data[this.bitNum >> 3] &= ~(1 << (this.bitNum & 0x7));
|
||||
}
|
||||
this.bitNum++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Write a signed integer: 1-bit sign flag + (bitCount-1) magnitude bits. */
|
||||
writeSignedInt(value: number, bitCount: number): void {
|
||||
if (value < 0) {
|
||||
this.writeFlag(true);
|
||||
this.writeInt(-value, bitCount - 1);
|
||||
} else {
|
||||
this.writeFlag(false);
|
||||
this.writeInt(value, bitCount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
writeU8(value: number): void {
|
||||
this.writeInt(value & 0xff, 8);
|
||||
}
|
||||
|
||||
writeU16(value: number): void {
|
||||
this.writeInt(value & 0xffff, 16);
|
||||
}
|
||||
|
||||
writeU32(value: number): void {
|
||||
this.writeInt(value >>> 0, 32);
|
||||
}
|
||||
|
||||
writeS32(value: number): void {
|
||||
this.writeU32(value | 0);
|
||||
}
|
||||
|
||||
/** Shared buffer for F32 writes. */
|
||||
private static readonly f32Buf = new ArrayBuffer(4);
|
||||
private static readonly f32View = new DataView(BitStreamWriter.f32Buf);
|
||||
private static readonly f32U8 = new Uint8Array(BitStreamWriter.f32Buf);
|
||||
|
||||
writeF32(value: number): void {
|
||||
BitStreamWriter.f32View.setFloat32(0, value, true);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
this.writeU8(BitStreamWriter.f32U8[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write a float normalized to [0, 1]. */
|
||||
writeFloat(value: number, bitCount: number): void {
|
||||
const maxVal = (1 << bitCount) - 1;
|
||||
this.writeInt(Math.round(value * maxVal), bitCount);
|
||||
}
|
||||
|
||||
/** Write a float normalized to [-1, 1]. */
|
||||
writeSignedFloat(value: number, bitCount: number): void {
|
||||
const maxVal = (1 << bitCount) - 1;
|
||||
this.writeInt(Math.round((value + 1.0) * 0.5 * maxVal), bitCount);
|
||||
}
|
||||
|
||||
writeRangedU32(value: number, rangeStart: number, rangeEnd: number): void {
|
||||
const rangeSize = rangeEnd - rangeStart + 1;
|
||||
const rangeBits = Math.ceil(Math.log2(rangeSize)) || 1;
|
||||
this.writeInt(value - rangeStart, rangeBits);
|
||||
}
|
||||
|
||||
/** Write raw bits from a Uint8Array. */
|
||||
writeBitsBuffer(data: Uint8Array, bitCount: number): void {
|
||||
for (let i = 0; i < bitCount; i++) {
|
||||
const byteIndex = i >> 3;
|
||||
const bitIndex = i & 0x7;
|
||||
const bit = (data[byteIndex] >> bitIndex) & 1;
|
||||
if (bit) {
|
||||
this.data[this.bitNum >> 3] |= 1 << (this.bitNum & 0x7);
|
||||
} else {
|
||||
this.data[this.bitNum >> 3] &= ~(1 << (this.bitNum & 0x7));
|
||||
}
|
||||
this.bitNum++;
|
||||
}
|
||||
}
|
||||
|
||||
writeBytes(bytes: Uint8Array): void {
|
||||
this.writeBitsBuffer(bytes, bytes.length * 8);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue