1 string wordwrap_buffer;
3 void wordwrap_buffer_put(string s)
5 wordwrap_buffer = strcat(wordwrap_buffer, s);
8 string wordwrap(string s, float l)
11 wordwrap_cb(s, l, wordwrap_buffer_put);
12 return wordwrap_buffer;
16 void wordwrap_buffer_sprint(string s)
18 wordwrap_buffer = strcat(wordwrap_buffer, s);
21 sprint(self, wordwrap_buffer);
26 void wordwrap_sprint(string s, float l)
29 wordwrap_cb(s, l, wordwrap_buffer_sprint);
30 if(wordwrap_buffer != "")
31 sprint(self, strcat(wordwrap_buffer, "\n"));
36 void wordwrap_cb(string s, float l, void(string) callback)
39 local float lleft, i, j, wlen;
43 for (i = 0;i < strlen(s);i++)
45 if (substring(s, i, 2) == "\\n")
51 else if (substring(s, i, 1) == "\n")
56 else if (substring(s, i, 1) == " ")
66 for (j = i+1;j < strlen(s);j++)
67 // ^^ this skips over the first character of a word, which
68 // is ALWAYS part of the word
69 // this is safe since if i+1 == strlen(s), i will become
70 // strlen(s)-1 at the end of this block and the function
71 // will terminate. A space can't be the first character we
72 // read here, and neither can a \n be the start, since these
73 // two cases have been handled above.
75 c = substring(s, j, 1);
82 // we need to keep this tempstring alive even if substring is
83 // called repeatedly, so call strcat even though we're not
93 callback(substring(s, i, wlen));
101 float dist_point_line(vector p, vector l0, vector ldir)
103 ldir = normalize(ldir);
105 // remove the component in line direction
106 p = p - (p * ldir) * ldir;
108 // vlen of the remaining vector
112 void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass)
141 float median(float a, float b, float c)
144 return bound(a, b, c);
145 return bound(c, b, a);
148 // converts a number to a string with the indicated number of decimals
149 // works for up to 10 decimals!
150 string ftos_decimals(float number, float decimals)
156 // if negative, cut off the sign first
158 return strcat("-", ftos_decimals(-number, decimals));
159 // it now is always positive!
162 number = floor(number * pow(10, decimals) + 0.5);
165 result = ftos(number);
166 len = strlen(result);
167 // does it have a decimal point (should not happen)? If there is one, it is always at len-7)
168 // if ftos had fucked it up, which should never happen: "34278.000000"
170 if(substring(result, len - 7, 1) == ".")
172 dprint("ftos(integer) has comma? Can't be. Affected result: ", result, "\n");
173 result = substring(result, 0, len - 7);
178 return result; // don't insert a point for zero decimals
179 // is it too short? If yes, insert leading zeroes
182 result = strcat(substring("0000000000", 0, decimals - len + 1), result);
185 // and now... INSERT THE POINT!
186 tmp = substring(result, len - decimals, decimals);
187 result = strcat(substring(result, 0, len - decimals), ".", tmp);
192 vector colormapPaletteColor(float c, float isPants)
196 case 0: return '0.733 0.733 0.733';
197 case 1: return '0.451 0.341 0.122';
198 case 2: return '0.000 0.733 0.733';
199 case 3: return '0.000 1.000 0.000';
200 case 4: return '1.000 0.000 0.000';
201 case 5: return '0.000 0.502 1.000';
202 case 6: return '0.812 0.561 0.169';
203 case 7: return '0.718 0.529 0.420';
204 case 8: return '0.765 0.545 0.667';
205 case 9: return '1.000 0.000 1.000';
206 case 10: return '0.639 0.529 0.482';
207 case 11: return '0.310 0.388 0.341';
208 case 12: return '1.000 1.000 0.000';
209 case 13: return '0.000 0.000 1.000';
210 case 14: return '1.000 0.502 0.000';
214 '1 0 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 0.0000000000))
215 + '0 1 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 2.0943951024))
216 + '0 0 1' * (0.502 + 0.498 * sin(time / 2.7182818285 + 4.1887902048));
219 '1 0 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 5.2359877560))
220 + '0 1 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 3.1415926536))
221 + '0 0 1' * (0.502 + 0.498 * sin(time / 3.1415926536 + 1.0471975512));
222 default: return '0.000 0.000 0.000';
226 // unzone the string, and return it as tempstring. Safe to be called on string_null
227 string fstrunzone(string s)
237 // Databases (hash tables)
238 #define DB_BUCKETS 8192
239 void db_save(float db, string pFilename)
242 fh = fopen(pFilename, FILE_WRITE);
244 error(strcat("Can't write DB to ", pFilename));
246 fputs(fh, strcat(ftos(DB_BUCKETS), "\n"));
247 for(i = 0; i < n; ++i)
248 fputs(fh, strcat(bufstr_get(db, i), "\n"));
252 float db_load(string pFilename)
254 float db, fh, i, j, n;
259 fh = fopen(pFilename, FILE_READ);
262 if(stof(fgets(fh)) == DB_BUCKETS)
265 while((l = fgets(fh)))
268 bufstr_set(db, i, l);
274 // different count of buckets?
275 // need to reorganize the database then (SLOW)
276 while((l = fgets(fh)))
278 n = tokenizebyseparator(l, "\\");
279 for(j = 0; j < n; j += 2)
280 db_put(db, argv(j), argv(j+1));
287 void db_close(float db)
292 string db_get(float db, string pKey)
295 h = mod(crc16(FALSE, pKey), DB_BUCKETS);
296 return infoget(bufstr_get(db, h), pKey);
299 void db_put(float db, string pKey, string pValue)
302 h = mod(crc16(FALSE, pKey), DB_BUCKETS);
303 bufstr_set(db, h, infoadd(bufstr_get(db, h), pKey, pValue));
310 db = db_load("foo.db");
311 print("LOADED. FILL...\n");
312 for(i = 0; i < DB_BUCKETS; ++i)
313 db_put(db, ftos(random()), "X");
314 print("FILLED. SAVE...\n");
315 db_save(db, "foo.db");
316 print("SAVED. CLOSE...\n");
321 // Multiline text file buffers
322 float buf_load(string pFilename)
329 fh = fopen(pFilename, FILE_READ);
333 while((l = fgets(fh)))
335 bufstr_set(buf, i, l);
342 void buf_save(float buf, string pFilename)
345 fh = fopen(pFilename, FILE_WRITE);
347 error(strcat("Can't write buf to ", pFilename));
348 n = buf_getsize(buf);
349 for(i = 0; i < n; ++i)
350 fputs(fh, strcat(bufstr_get(buf, i), "\n"));