Page 1 of 1

[INC] bits.inc

Posted: Sun Sep 13, 2026 7:16 am
by Archive-Poster
Macro substitutions for bit manipulation
My simple library for manipulate with bits:
Big thanks Void.Less for translate

Single bits
Bit flag operation is done everywhere with such macros:

Code: Select all

#define set_bit(%1,%2)        (%1 |= (1<<%2))
#define get_bit(%1,%2)        (%1 & (1<<%2))
#define clr_bit(%1,%2)        (%1 &= ~(1<<%2)) 
Example usage with enumerated flags:

Code: Select all

enum e_flags {
  FLAG_1,
  FLAG_2,
  FLAG_3,
  FLAG_4
}

new flag
set_bit(flag, FLAG_2)
get_bit(flag, FLAG_3) 
Multi-flag macros
For checking multiple bits at once:

Code: Select all

#define set_bits(%1,%2)       (%1 |= %2)
#define get_bits(%1,%2)       (%1 & %2)
#define clr_bits(%1,%2)       (%1 &= ~%2) 
Difference is that instead of bit position we use variable or constant with set of bit.

Example:

Code: Select all

// Define constants with necessary bits
#define CLIENT_FLAG_1   (1<<0)
#define CLIENT_FLAG_2   (1<<1)
#define CLIENT_FLAG_3   (1<<2)
#define CLIENT_FLAG_4   (1<<3)

// Array of flags for every player
new flag[32]

// Set two flags for player 1
set_bits(flag[1], CLIENT_FLAG_1 | CLIENT_FLAG_3)

// Clear 3 flags for player 23
clr_bits(flag[23], CLIENT_FLAG_1 | CLIENT_FLAG_4 | CLIENT_FLAG_2) 
Big bit amount
These macros are designed for setting single bits in big flag arrays

Code: Select all

#define set_big_bit(%1,%2)    (%1[%2>>5] |= 1<<(%2 & 31))
#define get_big_bit(%1,%2)    (%1[%2>>5] & 1<<(%2 & 31))
#define clr_big_bit(%1,%2)    (%1[%2>>5] &= ~(1 << (%2 & 31)))
If you need more than 32 flags in one variable, you can use string of any length as a flag container.

Code: Select all

new flags[4]
//possible 4 * 32 = 128 bits stored

set_big_bit(flags, 34)
get_big_bit(flags, 56)
clr_big_bit(flags, 101) 
Recommendations

Cerberus mainly use second type flags, and only 2 functions are used:

Code: Select all

#define CF_IS_BOT (1<<0)
#define CF_IS_HLTV (1<<1)
#define CF_IS_CONNECTED (1<<2)

new gUserFlag[33]

public bool:cerb_flag(id, flag) 
    return bool:(get_bits(gUserFlag[id], flag))
public set_cerb_flag(id, flag, value)
    value ? set_bits(gUserFlag[id], flag) : clr_bits(gUserFlag[id], flag)

// This simplifies setting and clearing of multiple flags
public client_connect(id) {
    set_cerb_flag(id, CF_IS_BOT | CF_IS_HLTV | CF_IS_CONNECTED, 0)
}

// You can use logical functions right away
public client_putinserver(id) {
    set_cerb_flag(id, CF_IS_BOT, is_user_bot(id))
    set_cerb_flag(id, CF_IS_HLTV, is_user_hltv(id))
    set_cerb_flag(id, CF_IS_CONNECTED, 1)
}