Add BlockPos type and Math.h
This commit is contained in:
parent
5e425e402f
commit
7c5beda081
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "util/Math.h"
|
||||||
|
|
||||||
#include "logging/Logger.h"
|
#include "logging/Logger.h"
|
||||||
|
|
||||||
constexpr unsigned long long operator"" KB(unsigned long long l)
|
constexpr unsigned long long operator"" KB(unsigned long long l)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/ByteUtil.h"
|
#include "util/ByteUtil.h"
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -71,6 +72,11 @@ namespace Feather
|
||||||
WriteString(string.c_str(), string.length());
|
WriteString(string.c_str(), string.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void WritePosition(BlockPos pos)
|
||||||
|
{
|
||||||
|
Write<int64_t>(pos.Encode());
|
||||||
|
}
|
||||||
|
|
||||||
inline void Finalize()
|
inline void Finalize()
|
||||||
{
|
{
|
||||||
PrependVarIntSize();
|
PrependVarIntSize();
|
||||||
|
|
33
src/Types.h
33
src/Types.h
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
#include "util/ByteUtil.h"
|
#include "util/ByteUtil.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -19,4 +20,36 @@ namespace Feather
|
||||||
.data = { ReverseBytes(uuid.data[0]), ReverseBytes(uuid.data[1]) }
|
.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)
|
count = extract_array_count(type)
|
||||||
type = extract_array_type(type)
|
type = extract_array_type(type)
|
||||||
|
|
||||||
|
# TODO: encode type sizes in Hjson data
|
||||||
if type == 'varint':
|
if type == 'varint':
|
||||||
return varint_max_size
|
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
|
return 8
|
||||||
elif type == 'int32' or type == 'uint32' or type == 'float':
|
elif type == 'int32' or type == 'uint32' or type == 'float':
|
||||||
return 4
|
return 4
|
||||||
|
@ -81,6 +82,8 @@ def get_rw_func(primitiveType, aliasedType, read):
|
||||||
return '{}VarInt<{}>'.format(prefix, primitiveType)
|
return '{}VarInt<{}>'.format(prefix, primitiveType)
|
||||||
elif aliasedType == 'string':
|
elif aliasedType == 'string':
|
||||||
return '{}String'.format(prefix)
|
return '{}String'.format(prefix)
|
||||||
|
elif aliasedType == 'position':
|
||||||
|
return '{}Position'.format(prefix)
|
||||||
else:
|
else:
|
||||||
return '{}<{}>'.format(prefix, primitiveType)
|
return '{}<{}>'.format(prefix, primitiveType)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
varint : int32_t
|
varint : int32_t
|
||||||
string : std::string
|
string : std::string
|
||||||
uuid : MinecraftUUID
|
uuid : MinecraftUUID
|
||||||
|
position: BlockPos
|
||||||
|
|
||||||
uint64 : uint64_t
|
uint64 : uint64_t
|
||||||
int64 : int64_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