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:
PHP Code:
#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:
PHP Code:
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:
PHP Code:
#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:
PHP Code:
// 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
PHP Code:
#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.
PHP Code:
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:
PHP Code:
#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)
}