]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/bits.qh
Mark [[eraseable]] most of the common functions in the lib directory. Since many...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / bits.qh
1 #pragma once
2
3 #include "log.qh"
4
5 #define BIT(n) (1 << (n))
6 #define BITS(n) (BIT(n) - 1)
7 #ifndef BRANCHLESS_BITSET
8         #define BITSET(var, mask, flag) (flag ? (var) | (mask) : (var) & ~(mask))
9 #else
10         #define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
11 #endif
12
13 [[eraseable]]
14 int lowestbit(int f)
15 {
16         f &= ~(f << 1);
17         f &= ~(f << 2);
18         f &= ~(f << 4);
19         f &= ~(f << 8);
20         f &= ~(f << 16);
21         return f;
22 }
23
24 [[eraseable]]
25 int randombit(int bits)
26 {
27         if (!(bits & (bits - 1)))  // this ONLY holds for powers of two!
28                 return bits;
29
30         int r = random();
31         int b = 0;
32         int n = 0;
33
34         for (int f = 1; f <= bits; f *= 2)
35         {
36                 if (bits & f)
37                 {
38                         ++n;
39                         r *= n;
40                         if (r <= 1) b = f;
41                         else r = (r - 1) / (n - 1);
42                 }
43         }
44         return b;
45 }
46
47 [[eraseable]]
48 int randombits(int bits, int k, bool error_return)
49 {
50         int r = 0;
51         while (k > 0 && bits != r)
52         {
53                 r += randombit(bits - r);
54                 --k;
55         }
56         if (error_return)
57                 if (k > 0) return -1;
58         // all
59         return r;
60 }
61
62 /*
63 void randombit_test(int bits, int iter)
64 {
65         while (iter > 0)
66         {
67                 LOG_INFO(ftos(randombit(bits)), "\n");
68                 --iter;
69         }
70 }
71 */
72
73 enum {
74         OP_SET,
75         OP_MIN,
76         OP_MAX,
77         OP_PLUS,
78         OP_MINUS
79 };
80
81 [[eraseable]]
82 bool GiveBit(entity e, .int fld, int bit, int op, int val)
83 {
84         int v0 = (e.(fld) & bit);
85         switch (op)
86         {
87                 case OP_SET:
88                         if (val > 0) e.(fld) |= bit;
89                         else e.(fld) &= ~bit;
90                         break;
91                 case OP_MIN:
92                 case OP_PLUS:
93                         if (val > 0) e.(fld) |= bit;
94                         break;
95                 case OP_MAX:
96                         if (val <= 0) e.(fld) &= ~bit;
97                         break;
98                 case OP_MINUS:
99                         if (val > 0) e.(fld) &= ~bit;
100                         break;
101         }
102         int v1 = (e.(fld) & bit);
103         return v0 != v1;
104 }
105
106 [[eraseable]]
107 bool GiveValue(entity e, .int fld, int op, int val)
108 {
109         int v0 = e.(fld);
110         switch (op)
111         {
112                 case OP_SET:
113                         e.(fld) = val;
114                         break;
115                 case OP_MIN:
116                         e.(fld) = max(e.(fld), val);  // min 100 cells = at least 100 cells
117                         break;
118                 case OP_MAX:
119                         e.(fld) = min(e.(fld), val);
120                         break;
121                 case OP_PLUS:
122                         e.(fld) += val;
123                         break;
124                 case OP_MINUS:
125                         e.(fld) -= val;
126                         break;
127         }
128         int v1 = e.(fld);
129         return v0 != v1;
130 }