Skip to content

Instantly share code, notes, and snippets.

@namrog84
Last active March 24, 2025 03:47
Show Gist options
  • Save namrog84/bebb1b659f58548283cb1787ef761abc to your computer and use it in GitHub Desktop.
Save namrog84/bebb1b659f58548283cb1787ef761abc to your computer and use it in GitHub Desktop.
// User-configurable bit allocations as compile-time constants
constexpr uint32 TAB_BITS = 8; // 8 bits = 256 possible tabs/pages
constexpr uint32 X_BITS = 8; // 8 bits = 256 possible X positions
constexpr uint32 Y_BITS = 8; // 8 bits = 256 possible Y positions
constexpr uint32 ROT_BITS = 2; // 2 bits = 4 possible rotation values (cardinal directions)
constexpr uint32 UNUSED_Bits = 6; // 6 bits reserved for future use. Or reallocation into above as needed.
// Calculate bit positions (Tab is in the lowest bits)
constexpr uint32 TAB_SHIFT = 0;
constexpr uint32 X_SHIFT = TAB_SHIFT + TAB_BITS;
constexpr uint32 Y_SHIFT = X_SHIFT + X_BITS;
constexpr uint32 ROT_SHIFT = Y_SHIFT + Y_BITS;
constexpr uint32 UNUSED_SHIFT = ROT_SHIFT + ROT_BITS;
// Calculate masks
constexpr uint32 TAB_MASK = (1 << TAB_BITS) - 1;
constexpr uint32 X_MASK = (1 << X_BITS) - 1;
constexpr uint32 Y_MASK = (1 << Y_BITS) - 1;
constexpr uint32 ROT_MASK = (1 << ROT_BITS) - 1;
constexpr uint32 UNUSED_MASK = (1 << UNUSED_BITS) - 1;
// Compile-time check to ensure we don't exceed 32 bits
static_assert(TAB_BITS + X_BITS + Y_BITS + ROT_BITS + UNUSED_BITS <= 32, "Bit allocation exceeds 32 bits");
// Packing - order independent
uint32 PackPosition(uint32 Tab, uint32 X, uint32 Y, uint32 Rot, uint32 Unused = 0) {
uint32 packedValue = 0;
packedValue |= (Tab & TAB_MASK) << TAB_SHIFT;
packedValue |= (X & X_MASK) << X_SHIFT;
packedValue |= (Y & Y_MASK) << Y_SHIFT;
packedValue |= (Rot & ROT_MASK) << ROT_SHIFT;
packedValue |= (Unused & UNUSED_MASK) << UNUSED_SHIFT;
return packedValue;
}
// Unpacking - order independent
void UnpackPosition(uint32 packedValue, uint32& Tab, uint32& X, uint32& Y, uint32& Rot) {
Tab = (packedValue >> TAB_SHIFT) & TAB_MASK;
X = (packedValue >> X_SHIFT) & X_MASK;
Y = (packedValue >> Y_SHIFT) & Y_MASK;
Rot = (packedValue >> ROT_SHIFT) & ROT_MASK;
Unused = (packedValue >> UNUSED_SHIFT) & UNUSED_MASK;
}
// Alternatively, you can have getters for individual components
uint32 GetTab(uint32 packedValue) { return (packedValue >> TAB_SHIFT) & TAB_MASK; }
uint32 GetX(uint32 packedValue) { return (packedValue >> X_SHIFT) & X_MASK; }
uint32 GetY(uint32 packedValue) { return (packedValue >> Y_SHIFT) & Y_MASK; }
uint32 GetRot(uint32 packedValue) { return (packedValue >> ROT_SHIFT) & ROT_MASK; }
uint32 GetUnused(uint32 packedValue) { return (packedValue >> UNUSED_SHIFT) & UNUSED_MASK; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment