Add BlockPos type and Math.h
This commit is contained in:
parent
5e425e402f
commit
7c5beda081
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/Math.h"
|
||||
|
||||
#include "logging/Logger.h"
|
||||
|
||||
constexpr unsigned long long operator"" KB(unsigned long long l)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/ByteUtil.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
@ -71,6 +72,11 @@ namespace Feather
|
|||
WriteString(string.c_str(), string.length());
|
||||
}
|
||||
|
||||
inline void WritePosition(BlockPos pos)
|
||||
{
|
||||
Write<int64_t>(pos.Encode());
|
||||
}
|
||||
|
||||
inline void Finalize()
|
||||
{
|
||||
PrependVarIntSize();
|
||||
|
|
33
src/Types.h
33
src/Types.h
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
#include "util/ByteUtil.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
@ -19,4 +20,36 @@ namespace Feather
|
|||
.data = { ReverseBytes(uuid.data[0]), ReverseBytes(uuid.data[1]) }
|
||||
};
|
||||
}
|
||||
|
||||
struct BlockPos
|
||||
{
|
||||
int32_t x, y, z;
|
||||
|
||||
BlockPos(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z) {}
|
||||
|
||||
inline int64_t Encode()
|
||||
{
|
||||
int64_t l = 0;
|
||||
l |= ((long)x & PACKED_X_MASK) << X_OFFSET;
|
||||
l |= ((long)y & PACKED_Y_MASK) << Y_OFFSET;
|
||||
l |= ((long)z & PACKED_Z_MASK) << Z_OFFSET;
|
||||
|
||||
return l;
|
||||
}
|
||||
private:
|
||||
|
||||
// X: 26 bits, Z: 26 bits, Y: 12 bits
|
||||
static const int PACKED_X_LENGTH = 1 + Math::CeilLog2(Math::RoundToPowerOf2(30000000)); // should be 26
|
||||
static const int PACKED_Z_LENGTH = PACKED_X_LENGTH; // same as X
|
||||
static const int PACKED_Y_LENGTH = 64 - PACKED_X_LENGTH - PACKED_Z_LENGTH; // should be 12
|
||||
|
||||
static const int64_t PACKED_X_MASK = (1 << PACKED_X_LENGTH) - 1;
|
||||
static const int64_t PACKED_Y_MASK = (1 << PACKED_Y_LENGTH) - 1;
|
||||
static const int64_t PACKED_Z_MASK = (1 << PACKED_Z_LENGTH) - 1;
|
||||
|
||||
// order is X Z Y
|
||||
static const int Y_OFFSET = 0;
|
||||
static const int Z_OFFSET = PACKED_Y_LENGTH;
|
||||
static const int X_OFFSET = PACKED_Y_LENGTH + PACKED_Z_LENGTH;
|
||||
};
|
||||
}
|
|
@ -45,9 +45,10 @@ def get_type_size(type):
|
|||
count = extract_array_count(type)
|
||||
type = extract_array_type(type)
|
||||
|
||||
# TODO: encode type sizes in Hjson data
|
||||
if type == 'varint':
|
||||
return varint_max_size
|
||||
elif type == 'int64' or type == 'uint64' or type == 'double':
|
||||
elif type == 'int64' or type == 'uint64' or type == 'double' or type == 'position':
|
||||
return 8
|
||||
elif type == 'int32' or type == 'uint32' or type == 'float':
|
||||
return 4
|
||||
|
@ -81,6 +82,8 @@ def get_rw_func(primitiveType, aliasedType, read):
|
|||
return '{}VarInt<{}>'.format(prefix, primitiveType)
|
||||
elif aliasedType == 'string':
|
||||
return '{}String'.format(prefix)
|
||||
elif aliasedType == 'position':
|
||||
return '{}Position'.format(prefix)
|
||||
else:
|
||||
return '{}<{}>'.format(prefix, primitiveType)
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
varint : int32_t
|
||||
string : std::string
|
||||
uuid : MinecraftUUID
|
||||
position: BlockPos
|
||||
|
||||
uint64 : uint64_t
|
||||
int64 : int64_t
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Feather::Math
|
||||
{
|
||||
// de Bruijn Sequence: B(2, 5) = 0000 0111 0111 1100 1011 0101 0011 0001. Contains all 32 distinct 5-bit strings.
|
||||
constexpr uint32_t DE_BRUIJN_SEQ = 0x077CB531U;
|
||||
|
||||
constexpr int MULTIPLY_DE_BRUIJN_BIT_POSITION[32] = {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
|
||||
|
||||
// Is x a power of two?
|
||||
inline constexpr bool IsPowerOf2(int x)
|
||||
{
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
// Smallest number 2^z that is greater than or equal to x
|
||||
// Precondition: x > 0
|
||||
inline constexpr int RoundToPowerOf2(int x)
|
||||
{
|
||||
x--;
|
||||
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
inline constexpr int CeilLog2(int x)
|
||||
{
|
||||
// Ensure x is power of 2
|
||||
x = IsPowerOf2(x) ? x : RoundToPowerOf2(x);
|
||||
|
||||
// The de Bruijn sequence contains all 32 distinct 5-bit strings
|
||||
// 27 is 32 - 5 and 0x1F (31) is the lower 5 bits 0001 1111
|
||||
return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)((int64_t)x * DE_BRUIJN_SEQ >> 27) & 0x1F];
|
||||
}
|
||||
|
||||
// log base 2
|
||||
inline constexpr int Log2(int x)
|
||||
{
|
||||
return CeilLog2(x) - (IsPowerOf2(x) ? 0 : 1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue