Skip to content

Instantly share code, notes, and snippets.

@meepen
Created August 5, 2016 16:51
Show Gist options
  • Save meepen/2a39868232d4118fc00ac28b87e3f4d7 to your computer and use it in GitHub Desktop.
Save meepen/2a39868232d4118fc00ac28b87e3f4d7 to your computer and use it in GitHub Desktop.
WriteCoordBitMP/ReadCoordBitMP in Garry's Mod Lua (for prediction fixing!!!)
local function encodefloat(f, bIntegral, bLowPrecision)
local signbit = (f <= -( bLowPrecision and COORD_RESOLUTION_LOWPRECISION or COORD_RESOLUTION ));
local intval = math.floor(math.abs(f));
local fractval = bLowPrecision and
( bit.band(math.floor(math.abs(f*COORD_DENOMINATOR_LOWPRECISION)), (COORD_DENOMINATOR_LOWPRECISION-1))) or
( bit.band(math.floor(math.abs(f*COORD_DENOMINATOR)), (COORD_DENOMINATOR-1) ));
local bInBounds = intval < (2 ^ COORD_INTEGER_BITS_MP );
--[[ unsigned ]] local intvalret, fractvalret
local INBOUNDS, INTVAL, SIGN
if ( bIntegral ) then
-- Integer encoding: in-bounds bit, nonzero bit, optional sign bit + integer value bits
if (0 ~= intval) then
-- Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
intvalret = intval - 1;
SIGN = signbit
INBOUNDS = bInBounds
INTVAL = true
else
INBOUNDS = bInBounds
end
else
-- Float encoding: in-bounds bit, integer bit, sign bit, fraction value bits, optional integer value bits
if (intval ~= 0) then
-- Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
intvalret = intval - 1;
SIGN = signbit
INBOUNDS = bInBounds
INTVAL = true
fractvalret = fractval
else
SIGN = signbit
INBOUNDS = bInBounds
INTVAL = false
fractvalret = fractval
end
end
return INBOUNDS, INTVAL, SIGN, intvalret, fractvalret;
end
local mul_table =
{
1/(2^COORD_FRACTIONAL_BITS),
-1/(2^COORD_FRACTIONAL_BITS),
1/(2^COORD_FRACTIONAL_BITS_MP_LOWPRECISION),
-1/(2^COORD_FRACTIONAL_BITS_MP_LOWPRECISION)
};
local function decodefloat(bIntegral, bLowPrecision, INBOUNDS, INTVAL, SIGN, intvalret, fractvalret)
-- BitCoordMP float encoding: inbounds bit, integer bit, sign bit, optional int bits, float bits
-- BitCoordMP integer encoding: inbounds bit, integer bit, optional sign bit, optional int bits.
-- int bits are always encoded as (value - 1) since zero is handled by the integer bit
-- With integer-only encoding, the presence of the third bit depends on the second
if ( bIntegral ) then
if ( INTVAL ) then
-- Read the third bit and the integer portion together at once
-- Remap from [0,N] to [1,N+1]
intval = math.floor(intvalret * 2^-1) + 1;
return (intvalret % 2 == 1) and -intval or intval;
end
return 0;
end
local bits = fractvalret
-- equivalent to: float multiply = mul_table[ ((flags & SIGN) ? 1 : 0) + bLowPrecision*2 ];
--float multiply = *(float*)((uintptr_t)&mul_table[0] + (flags & 4) + bLowPrecision*8);
local multiply = mul_table[(SIGN and 1 or 0) + (bLowPrecision and 1 or 0)*2 + 1]
if ( INTVAL ) then
-- Shuffle the bits to remap the integer portion from [0,N] to [1,N+1]
-- and then paste in front of the fractional parts so we only need one
-- int-to-float conversion.
local fracbits = fractvalret
local intpart = intvalret
local intbitsLow = intpart * 2 ^ COORD_FRACTIONAL_BITS_MP_LOWPRECISION;
local intbits = intpart * 2 ^ COORD_FRACTIONAL_BITS;
local selectNotLow = (bLowPrecision and 1 or 0) - 1;
intbits = intbits - intbitsLow;
intbits = bit.band(intbits, selectNotLow);
intbits = intbits + intbitsLow;
bits = bit.bor(fracbits, intbits);
end
return math.floor(bits) * multiply;
end
local function networkedfloatencode(f)
return decodefloat(false, false, encodefloat(f, false, false))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment