]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/common/util.qc
start of mapinfo system; beware: menu-div0test now starts up longer for the first...
[divverent/nexuiz.git] / data / qcsrc / common / util.qc
1 string wordwrap_buffer;
2
3 void wordwrap_buffer_put(string s)
4 {
5         wordwrap_buffer = strcat(wordwrap_buffer, s);
6 }
7
8 string wordwrap(string s, float l)
9 {
10         wordwrap_buffer = "";
11         wordwrap_cb(s, l, wordwrap_buffer_put);
12         return wordwrap_buffer;
13 }
14
15 #ifndef MENUQC
16 void wordwrap_buffer_sprint(string s)
17 {
18         wordwrap_buffer = strcat(wordwrap_buffer, s);
19         if(s == "\n")
20         {
21                 sprint(self, wordwrap_buffer);
22                 wordwrap_buffer = "";
23         }
24 }
25
26 void wordwrap_sprint(string s, float l)
27 {
28         wordwrap_buffer = "";
29         wordwrap_cb(s, l, wordwrap_buffer_sprint);
30         if(wordwrap_buffer != "")
31                 sprint(self, strcat(wordwrap_buffer, "\n"));
32         return;
33 }
34 #endif
35
36 void wordwrap_cb(string s, float l, void(string) callback)
37 {
38         local string c;
39         local float lleft, i, j, wlen;
40
41         s = strzone(s);
42         lleft = l;
43         for (i = 0;i < strlen(s);i++)
44         {
45                 if (substring(s, i, 2) == "\\n")
46                 {
47                         callback("\n");
48                         lleft = l;
49                         i++;
50                 }
51                 else if (substring(s, i, 1) == " ")
52                 {
53                         if (lleft > 0)
54                         {
55                                 callback(" ");
56                                 lleft = lleft - 1;
57                         }
58                 }
59                 else
60                 {
61                         for (j = i+1;j < strlen(s);j++)
62                                 //    ^^ this skips over the first character of a word, which
63                                 //       is ALWAYS part of the word
64                                 //       this is safe since if i+1 == strlen(s), i will become
65                                 //       strlen(s)-1 at the end of this block and the function
66                                 //       will terminate. A space can't be the first character we
67                                 //       read here, and neither can a \n be the start, since these
68                                 //       two cases have been handled above.
69                         {
70                                 c = substring(s, j, 1);
71                                 if (c == " ")
72                                         break;
73                                 if (c == "\\")
74                                         break;
75                                 // we need to keep this tempstring alive even if substring is
76                                 // called repeatedly, so call strcat even though we're not
77                                 // doing anything
78                                 callback("");
79                         }
80                         wlen = j - i;
81                         if (lleft < wlen)
82                         {
83                                 callback("\n");
84                                 lleft = l;
85                         }
86                         callback(substring(s, i, wlen));
87                         lleft = lleft - wlen;
88                         i = j - 1;
89                 }
90         }
91         strunzone(s);
92 }
93
94 float dist_point_line(vector p, vector l0, vector ldir)
95 {
96         ldir = normalize(ldir);
97         
98         // remove the component in line direction
99         p = p - (p * ldir) * ldir;
100
101         // vlen of the remaining vector
102         return vlen(p);
103 }
104
105 void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass)
106 {
107         entity e;
108         e = start;
109         funcPre(pass, e);
110         while(e.downleft)
111         {
112                 e = e.downleft;
113                 funcPre(pass, e);
114         }
115         funcPost(pass, e);
116         while(e != start)
117         {
118                 if(e.right)
119                 {
120                         e = e.right;
121                         funcPre(pass, e);
122                         while(e.downleft)
123                         {
124                                 e = e.downleft;
125                                 funcPre(pass, e);
126                         }
127                 }
128                 else
129                         e = e.up;
130                 funcPost(pass, e);
131         }
132 }
133
134 float median(float a, float b, float c)
135 {
136         if(a < c)
137                 return bound(a, b, c);
138         return bound(c, b, a);
139 }
140
141 // converts a number to a string with the indicated number of decimals
142 // works for up to 10 decimals!
143 string ftos_decimals(float number, float decimals)
144 {
145         string result;
146         string tmp;
147         float len;
148
149         // if negative, cut off the sign first
150         if(number < 0)
151                 return strcat("-", ftos_decimals(-number, decimals));
152         // it now is always positive!
153
154         // 3.516 -> 352
155         number = floor(number * pow(10, decimals) + 0.5);
156
157         // 352 -> "352"
158         result = ftos(number);
159         len = strlen(result);
160         // does it have a decimal point (should not happen)? If there is one, it is always at len-7)
161                 // if ftos had fucked it up, which should never happen: "34278.000000"
162         if(len >= 7)
163                 if(substring(result, len - 7, 1) == ".")
164                 {
165                         dprint("ftos(integer) has comma? Can't be. Affected result: ", result, "\n");
166                         result = substring(result, 0, len - 7);
167                         len -= 7;
168                 }
169                 // "34278"
170         if(decimals == 0)
171                 return result; // don't insert a point for zero decimals
172         // is it too short? If yes, insert leading zeroes
173         if(len <= decimals)
174         {
175                 result = strcat(substring("0000000000", 0, decimals - len + 1), result);
176                 len = decimals + 1;
177         }
178         // and now... INSERT THE POINT!
179         tmp = substring(result, len - decimals, decimals);
180         result = strcat(substring(result, 0, len - decimals), ".", tmp);
181         return result;
182 }
183
184 float time;
185 vector colormapPaletteColor(float c, float isPants)
186 {
187         switch(c)
188         {
189                 case  0: return '0.733 0.733 0.733';
190                 case  1: return '0.451 0.341 0.122';
191                 case  2: return '0.000 0.733 0.733';
192                 case  3: return '0.000 1.000 0.000';
193                 case  4: return '1.000 0.000 0.000';
194                 case  5: return '0.000 0.502 1.000';
195                 case  6: return '0.812 0.561 0.169';
196                 case  7: return '0.718 0.529 0.420';
197                 case  8: return '0.765 0.545 0.667';
198                 case  9: return '1.000 0.000 1.000';
199                 case 10: return '0.639 0.529 0.482';
200                 case 11: return '0.310 0.388 0.341';
201                 case 12: return '1.000 1.000 0.000';
202                 case 13: return '0.000 0.000 1.000';
203                 case 14: return '1.000 0.502 0.000';
204                 case 15:
205                         if(isPants)
206                                 return
207                                           '1 0 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 0.0000000000))
208                                         + '0 1 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 2.0943951024))
209                                         + '0 0 1' * (0.502 + 0.498 * sin(time / 2.7182818285 + 4.1887902048));
210                         else
211                                 return
212                                           '1 0 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 5.2359877560))
213                                         + '0 1 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 3.1415926536))
214                                         + '0 0 1' * (0.502 + 0.498 * sin(time / 3.1415926536 + 1.0471975512));
215                 default: return '0.000 0.000 0.000';
216         }
217 }