]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/bits.qh
Merge branch 'terencehill/vec2_optimizations' into 'master'
[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 /*
60 void randombit_test(int bits, int iter)
61 {
62         while (iter > 0)
63         {
64                 LOG_INFO(ftos(randombit(bits)), "\n");
65                 --iter;
66         }
67 }
68 */
69
70 enum {
71         OP_SET,
72         OP_MIN,
73         OP_MAX,
74         OP_PLUS,
75         OP_MINUS
76 };
77
78 bool GiveBit(entity e, .int fld, int bit, int op, int val)
79 {
80         int v0 = (e.(fld) & bit);
81         switch (op)
82         {
83                 case OP_SET:
84                         if (val > 0) e.(fld) |= bit;
85                         else e.(fld) &= ~bit;
86                         break;
87                 case OP_MIN:
88                 case OP_PLUS:
89                         if (val > 0) e.(fld) |= bit;
90                         break;
91                 case OP_MAX:
92                         if (val <= 0) e.(fld) &= ~bit;
93                         break;
94                 case OP_MINUS:
95                         if (val > 0) e.(fld) &= ~bit;
96                         break;
97         }
98         int v1 = (e.(fld) & bit);
99         return v0 != v1;
100 }
101
102 bool GiveValue(entity e, .int fld, int op, int val)
103 {
104         int v0 = e.(fld);
105         switch (op)
106         {
107                 case OP_SET:
108                         e.(fld) = val;
109                         break;
110                 case OP_MIN:
111                         e.(fld) = max(e.(fld), val);  // min 100 cells = at least 100 cells
112                         break;
113                 case OP_MAX:
114                         e.(fld) = min(e.(fld), val);
115                         break;
116                 case OP_PLUS:
117                         e.(fld) += val;
118                         break;
119                 case OP_MINUS:
120                         e.(fld) -= val;
121                         break;
122         }
123         int v1 = e.(fld);
124         return v0 != v1;
125 }