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