88 lines
2.4 KiB
C++
88 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include "Common.h"
|
|
#include "util/ByteUtil.h"
|
|
|
|
#include <cstdint>
|
|
#include <array>
|
|
|
|
namespace Feather
|
|
{
|
|
struct MinecraftUUID
|
|
{
|
|
std::array<uint64_t, 2> data;
|
|
};
|
|
|
|
inline MinecraftUUID ReverseBytes(MinecraftUUID uuid)
|
|
{
|
|
return MinecraftUUID
|
|
{
|
|
.data = { ReverseBytes(uuid.data[0]), ReverseBytes(uuid.data[1]) }
|
|
};
|
|
}
|
|
|
|
struct BlockPos
|
|
{
|
|
const 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;
|
|
};
|
|
|
|
struct ChunkPos
|
|
{
|
|
const int32_t x, z;
|
|
|
|
ChunkPos(int32_t x, int32_t z) : x(x), z(z) {}
|
|
|
|
// Coordinate of the 16x16 chunk containing this block
|
|
ChunkPos(BlockPos pos) : x(pos.x >> 4), z(pos.z >> 4) {}
|
|
|
|
// Decode from packed int64
|
|
ChunkPos(int64_t packed) : x(packed), z(packed >> 32) {}
|
|
|
|
// Pack into one int64
|
|
inline int64_t Encode()
|
|
{
|
|
return ((int64_t)x & 0xFFFFFFFF) | (((int64_t)z & 0xFFFFFFFF) << 32);
|
|
}
|
|
};
|
|
|
|
// Which 32x32 chunk region file (r.<x>.<z>.mca) the chunk is stored in
|
|
struct RegionPos
|
|
{
|
|
const int32_t x, z;
|
|
RegionPos(ChunkPos pos) : x(pos.x >> 5), z(pos.z >> 5) {}
|
|
};
|
|
|
|
// Position of chunk relative to its region
|
|
struct RegionLocalPos
|
|
{
|
|
const int32_t x, z;
|
|
RegionLocalPos(ChunkPos pos) : x(pos.x & 0x1F), z(pos.z & 0x1F) {}
|
|
};
|
|
} |