PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/quakeforge/branches/release_0_5_2/libs/gamecode/builtins/pr_cmds.c

#
C | 882 lines | 636 code | 100 blank | 146 comment | 123 complexity | ecd491048070ca0291f9fd80b08768a0 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-3.0, AGPL-1.0, Unlicense
  1. /*
  2. pr_cmds.c
  3. (description)
  4. Copyright (C) 1996-1997 Id Software, Inc.
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. See the GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to:
  15. Free Software Foundation, Inc.
  16. 59 Temple Place - Suite 330
  17. Boston, MA 02111-1307, USA
  18. */
  19. static const char rcsid[] =
  20. "$Id: pr_cmds.c 8463 2002-09-07 06:48:15Z taniwha $";
  21. #ifdef HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24. #ifdef HAVE_ERRNO_H
  25. # include <errno.h>
  26. #endif
  27. #ifdef HAVE_STRING_H
  28. # include <string.h>
  29. #endif
  30. #ifdef HAVE_STRINGS_H
  31. # include <strings.h>
  32. #endif
  33. #include <stdlib.h>
  34. #include "QF/clip_hull.h"
  35. #include "QF/cmd.h"
  36. #include "QF/cvar.h"
  37. #include "QF/mathlib.h"
  38. #include "QF/msg.h"
  39. #include "QF/progs.h"
  40. #include "QF/sys.h"
  41. #include "QF/va.h"
  42. #include "QF/zone.h"
  43. #include "compat.h"
  44. const char *pr_gametype = "";
  45. /* BUILT-IN FUNCTIONS */
  46. // FIXME: Hunk_TempAlloc, Sys_Printf, Cvar_*, PR_SetString, PR_RunError, ED_PrintEdicts, PF_traceon, PF_traceoff, ED_PrintNum, PR_FindBuiltin isn't threadsafe/reentrant
  47. const char *
  48. PF_VarString (progs_t *pr, int first)
  49. {
  50. char *out;
  51. int len, i;
  52. for (len = 0, i = first; i < pr->pr_argc; i++)
  53. len += strlen (G_STRING (pr, (OFS_PARM0 + i * 3)));
  54. out = Hunk_TempAlloc (len + 1);
  55. out[0] = 0;
  56. for (i = first; i < pr->pr_argc; i++)
  57. strcat (out, G_STRING (pr, (OFS_PARM0 + i * 3)));
  58. return out;
  59. }
  60. /*
  61. PF_normalize
  62. vector normalize(vector)
  63. */
  64. void
  65. PF_normalize (progs_t *pr)
  66. {
  67. float new;
  68. float *value1;
  69. vec3_t newvalue;
  70. value1 = P_VECTOR (pr, 0);
  71. new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] *
  72. value1[2];
  73. new = sqrt (new);
  74. if (new == 0)
  75. newvalue[0] = newvalue[1] = newvalue[2] = 0;
  76. else {
  77. new = 1 / new;
  78. newvalue[0] = value1[0] * new;
  79. newvalue[1] = value1[1] * new;
  80. newvalue[2] = value1[2] * new;
  81. }
  82. VectorCopy (newvalue, R_VECTOR (pr));
  83. }
  84. /*
  85. PF_vlen
  86. scalar vlen(vector)
  87. */
  88. void
  89. PF_vlen (progs_t *pr)
  90. {
  91. float new;
  92. float *value1;
  93. value1 = P_VECTOR (pr, 0);
  94. new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] *
  95. value1[2];
  96. new = sqrt (new);
  97. R_FLOAT (pr) = new;
  98. }
  99. /*
  100. PF_vectoyaw
  101. float vectoyaw(vector)
  102. */
  103. void
  104. PF_vectoyaw (progs_t *pr)
  105. {
  106. float yaw;
  107. float *value1;
  108. value1 = P_VECTOR (pr, 0);
  109. if (value1[1] == 0 && value1[0] == 0)
  110. yaw = 0;
  111. else {
  112. yaw = (int) (atan2 (value1[1], value1[0]) * 180 / M_PI);
  113. if (yaw < 0)
  114. yaw += 360;
  115. }
  116. R_FLOAT (pr) = yaw;
  117. }
  118. /*
  119. PF_vectoangles
  120. vector vectoangles(vector)
  121. */
  122. void
  123. PF_vectoangles (progs_t *pr)
  124. {
  125. float forward, pitch, yaw;
  126. float *value1;
  127. value1 = P_VECTOR (pr, 0);
  128. if (value1[1] == 0 && value1[0] == 0) {
  129. yaw = 0;
  130. if (value1[2] > 0)
  131. pitch = 90;
  132. else
  133. pitch = 270;
  134. } else {
  135. yaw = (int) (atan2 (value1[1], value1[0]) * 180 / M_PI);
  136. if (yaw < 0)
  137. yaw += 360;
  138. forward = sqrt (value1[0] * value1[0] + value1[1] * value1[1]);
  139. pitch = (int) (atan2 (value1[2], forward) * 180 / M_PI);
  140. if (pitch < 0)
  141. pitch += 360;
  142. }
  143. R_VECTOR (pr)[0] = pitch;
  144. R_VECTOR (pr)[1] = yaw;
  145. R_VECTOR (pr)[2] = 0;
  146. }
  147. /*
  148. PF_Random
  149. Returns a number from 0<= num < 1
  150. random()
  151. */
  152. void
  153. PF_random (progs_t *pr)
  154. {
  155. float num;
  156. num = (rand () & 0x7fff) / ((float) 0x7fff);
  157. R_FLOAT (pr) = num;
  158. }
  159. /*
  160. PF_break
  161. break()
  162. */
  163. void
  164. PF_break (progs_t *pr)
  165. {
  166. Sys_Printf ("break statement\n");
  167. //*(int *) -4 = 0; // dump to debugger
  168. PR_DumpState (pr);
  169. // PR_RunError (pr, "break statement");
  170. }
  171. #if 0
  172. /*
  173. PF_localcmd
  174. Sends text to the host's execution buffer
  175. localcmd (string)
  176. */
  177. void
  178. PF_localcmd (progs_t *pr)
  179. {
  180. const char *str;
  181. str = P_STRING (pr, 0);
  182. Cbuf_AddText (str);
  183. }
  184. #endif
  185. /*
  186. PF_cvar
  187. float cvar (string)
  188. */
  189. void
  190. PF_cvar (progs_t *pr)
  191. {
  192. const char *str;
  193. str = P_STRING (pr, 0);
  194. R_FLOAT (pr) = Cvar_VariableValue (str);
  195. }
  196. /*
  197. PF_cvar_set
  198. float cvar (string)
  199. */
  200. void
  201. PF_cvar_set (progs_t *pr)
  202. {
  203. const char *var_name, *val;
  204. cvar_t *var;
  205. var_name = P_STRING (pr, 0);
  206. val = P_STRING (pr, 1);
  207. var = Cvar_FindVar (var_name);
  208. if (!var)
  209. var = Cvar_FindAlias (var_name);
  210. if (!var) {
  211. Sys_Printf ("PF_cvar_set: variable %s not found\n", var_name);
  212. return;
  213. }
  214. Cvar_Set (var, val);
  215. }
  216. void
  217. PF_fabs (progs_t *pr)
  218. {
  219. float v;
  220. v = P_FLOAT (pr, 0);
  221. R_FLOAT (pr) = fabs (v);
  222. }
  223. // entity (entity start, .string field, string match) find = #5;
  224. void
  225. PF_Find (progs_t *pr)
  226. {
  227. const char *s = 0, *t; // ev_string
  228. int i; // ev_vector
  229. int e, f;
  230. etype_t type;
  231. ddef_t *field_def;
  232. edict_t *ed;
  233. e = P_EDICTNUM (pr, 0);
  234. f = P_INT (pr, 1);
  235. field_def = ED_FieldAtOfs (pr, f);
  236. if (!field_def)
  237. PR_RunError (pr, "PF_Find: bad search field");
  238. type = field_def->type & ~DEF_SAVEGLOBAL;
  239. if (type == ev_string) {
  240. s = P_STRING (pr, 2);
  241. if (!s)
  242. PR_RunError (pr, "PF_Find: bad search string");
  243. }
  244. for (e++; e < *pr->num_edicts; e++) {
  245. ed = EDICT_NUM (pr, e);
  246. if (ed->free)
  247. continue;
  248. switch (type) {
  249. case ev_string:
  250. t = E_STRING (pr, ed, f);
  251. if (!t)
  252. continue;
  253. if (strcmp (t, s))
  254. continue;
  255. RETURN_EDICT (pr, ed);
  256. return;
  257. case ev_float:
  258. if (P_FLOAT (pr, 2) != E_FLOAT (ed, f))
  259. continue;
  260. RETURN_EDICT (pr, ed);
  261. return;
  262. case ev_vector:
  263. for (i = 0; i <= 2; i++)
  264. if (P_FLOAT (pr, 2 + i) != E_FLOAT (ed, f + i))
  265. continue;
  266. RETURN_EDICT (pr, ed);
  267. return;
  268. case ev_integer:
  269. case ev_entity:
  270. if (P_INT (pr, 2) != E_INT (ed, f))
  271. continue;
  272. RETURN_EDICT (pr, ed);
  273. return;
  274. default:
  275. PR_Error (pr, "PF_Find: unsupported search field");
  276. }
  277. }
  278. RETURN_EDICT (pr, *pr->edicts);
  279. }
  280. void
  281. PF_coredump (progs_t *pr)
  282. {
  283. ED_PrintEdicts (pr, "");
  284. }
  285. void
  286. PF_traceon (progs_t *pr)
  287. {
  288. pr->pr_trace = true;
  289. }
  290. void
  291. PF_traceoff (progs_t *pr)
  292. {
  293. pr->pr_trace = false;
  294. }
  295. void
  296. PF_eprint (progs_t *pr)
  297. {
  298. ED_PrintNum (pr, P_EDICTNUM (pr, 0));
  299. }
  300. void
  301. PF_dprint (progs_t *pr)
  302. {
  303. Sys_Printf ("%s", PF_VarString (pr, 0));
  304. }
  305. void
  306. PF_rint (progs_t *pr)
  307. {
  308. float f;
  309. f = P_FLOAT (pr, 0);
  310. if (f > 0)
  311. R_FLOAT (pr) = (int) (f + 0.5);
  312. else
  313. R_FLOAT (pr) = (int) (f - 0.5);
  314. }
  315. void
  316. PF_floor (progs_t *pr)
  317. {
  318. R_FLOAT (pr) = floor (P_FLOAT (pr, 0));
  319. }
  320. void
  321. PF_ceil (progs_t *pr)
  322. {
  323. R_FLOAT (pr) = ceil (P_FLOAT (pr, 0));
  324. }
  325. /*
  326. PF_nextent
  327. entity nextent(entity)
  328. */
  329. void
  330. PF_nextent (progs_t *pr)
  331. {
  332. int i;
  333. edict_t *ent;
  334. i = P_EDICTNUM (pr, 0);
  335. while (1) {
  336. i++;
  337. if (i == *pr->num_edicts) {
  338. RETURN_EDICT (pr, *pr->edicts);
  339. return;
  340. }
  341. ent = EDICT_NUM (pr, i);
  342. if (!ent->free) {
  343. RETURN_EDICT (pr, ent);
  344. return;
  345. }
  346. }
  347. }
  348. // we assume that ints are smaller than floats
  349. #ifdef FLT_MAX_10_EXP
  350. # define STRING_BUF (FLT_MAX_10_EXP + 8)
  351. #else
  352. # define STRING_BUF 128
  353. #endif
  354. /*
  355. PF_ftoi
  356. integer (float f) ftoi
  357. */
  358. void
  359. PF_ftoi (progs_t *pr)
  360. {
  361. R_INT (pr) = P_FLOAT (pr, 0);
  362. }
  363. /*
  364. PF_ftos
  365. string (float f) ftos
  366. */
  367. void
  368. PF_ftos (progs_t *pr)
  369. {
  370. char string[STRING_BUF];
  371. int i;
  372. // trimming 0s idea thanks to Maddes
  373. i = snprintf (string, sizeof (string), "%1.6f", P_FLOAT (pr, 0)) - 1;
  374. for (; i > 0; i--) {
  375. if (string[i] == '0')
  376. string[i] = '\0';
  377. else if (string[i] == '.') {
  378. string[i] = '\0';
  379. break;
  380. } else
  381. break;
  382. }
  383. RETURN_STRING (pr, string);
  384. }
  385. /*
  386. PF_itof
  387. float (integer i) itof
  388. */
  389. void
  390. PF_itof (progs_t *pr)
  391. {
  392. R_FLOAT (pr) = P_INT (pr, 0);
  393. }
  394. /*
  395. PF_itos
  396. string (integer i) itos
  397. */
  398. void
  399. PF_itos (progs_t *pr)
  400. {
  401. char string[STRING_BUF];
  402. snprintf (string, sizeof (string), "%d", P_INT (pr, 0));
  403. RETURN_STRING (pr, string);
  404. }
  405. /*
  406. PF_stof
  407. float (string s) stof
  408. */
  409. void
  410. PF_stof (progs_t *pr)
  411. {
  412. R_FLOAT (pr) = atof (P_STRING (pr, 0));
  413. }
  414. /*
  415. PF_stoi
  416. integer (string s) stoi
  417. */
  418. void
  419. PF_stoi (progs_t *pr)
  420. {
  421. R_INT (pr) = atoi (P_STRING (pr, 0));
  422. }
  423. /*
  424. PF_stov
  425. vector (string s) stov
  426. */
  427. void
  428. PF_stov (progs_t *pr)
  429. {
  430. float v[3] = {0, 0, 0};
  431. sscanf (P_STRING (pr, 0), "'%f %f %f'", v, v + 1, v + 2);
  432. RETURN_VECTOR (pr, v);
  433. }
  434. /*
  435. PF_vtos
  436. string (vector v) vtos
  437. */
  438. void
  439. PF_vtos (progs_t *pr)
  440. {
  441. char string[STRING_BUF * 3 + 5];
  442. snprintf (string, sizeof (string), "'%5.1f %5.1f %5.1f'",
  443. P_VECTOR (pr, 0)[0],
  444. P_VECTOR (pr, 0)[1],
  445. P_VECTOR (pr, 0)[2]);
  446. RETURN_STRING (pr, string);
  447. }
  448. /*
  449. PF_strlen
  450. float(string s) strlen
  451. */
  452. void
  453. PF_strlen (progs_t *pr)
  454. {
  455. const char *s;
  456. s = P_STRING (pr, 0);
  457. R_FLOAT (pr) = strlen(s);
  458. }
  459. /*
  460. PF_charcount
  461. float(string char, string s) charcount
  462. */
  463. void
  464. PF_charcount (progs_t *pr)
  465. {
  466. char goal;
  467. const char *s;
  468. int count;
  469. goal = (P_STRING (pr, 0))[0];
  470. if (goal == '\0') {
  471. R_FLOAT (pr) = 0;
  472. return;
  473. }
  474. count = 0;
  475. s = P_STRING (pr, 1);
  476. while (*s) {
  477. if (*s == goal)
  478. count++;
  479. s++;
  480. }
  481. R_FLOAT (pr) = count;
  482. }
  483. #if (INT_MAX == 2147483647) && (INT_MIN == -2147483648)
  484. # define INT_WIDTH 11
  485. #else /* I hope... */
  486. # define INT_WIDTH 20
  487. #endif
  488. #define MAX_ARG 23
  489. void
  490. PF_sprintf (progs_t *pr)
  491. {
  492. char *format;
  493. char *c; // current
  494. char *out = 0;
  495. char new_format[INT_WIDTH * 2 + 9]; // "%0-+ #." and conversion
  496. int fmt_alternate, fmt_leadzero, fmt_leftjust, fmt_minwidth,
  497. fmt_precision, fmt_signed, fmt_space, fmt_type, looping,
  498. new_format_i, ret;
  499. int curarg = 3, out_max = 32, out_size = 0;
  500. format = P_STRING (pr, 0);
  501. c = format;
  502. out = malloc (out_max);
  503. if (!out)
  504. goto mallocerror;
  505. while (*c) {
  506. if (*c == '%' && c[1] != '%' && c[1] != 's') {
  507. c++;
  508. if (curarg > MAX_ARG)
  509. goto maxargs;
  510. // flags
  511. looping = 1;
  512. fmt_leadzero = 0;
  513. fmt_leftjust = 0;
  514. fmt_signed = 0;
  515. fmt_space = 0;
  516. fmt_alternate = 0;
  517. while (looping) {
  518. switch (*c) {
  519. case '0': fmt_leadzero = 1; break;
  520. case '-': fmt_leftjust = 1; break;
  521. case '+': fmt_signed = 1; break;
  522. case ' ': fmt_space = 1; break;
  523. case '#': fmt_alternate = 1; break;
  524. case '\0': goto endofstring;
  525. default: looping = 0; continue;
  526. }
  527. c++;
  528. }
  529. // minimum field width
  530. fmt_minwidth = 0;
  531. if (*c >= '1' && *c <= '9')
  532. while (*c >= '0' && *c <= '9') {
  533. fmt_minwidth *= 10;
  534. fmt_minwidth += *c - '0';
  535. c++;
  536. }
  537. else if (*c == '*') {
  538. fmt_minwidth = P_INT (pr, 0 + curarg);
  539. curarg += 3;
  540. }
  541. // precision
  542. fmt_precision = -1;
  543. if (*c == '.') {
  544. c++;
  545. if (*c >= '0' && *c <= '9') {
  546. fmt_precision = 0;
  547. while (*c >= '0' && *c <= '9') {
  548. fmt_precision *= 10;
  549. fmt_precision += *c - '0';
  550. c++;
  551. }
  552. } else if (*c == '*') {
  553. fmt_precision = P_INT (pr, 0 + curarg);
  554. curarg += 3;
  555. }
  556. }
  557. if (!*c)
  558. goto endofstring;
  559. // length? Nope, not in QC
  560. fmt_type = *c++;
  561. // some preperation
  562. if (fmt_precision < 0)
  563. switch (fmt_type) {
  564. case 'i': fmt_precision = 0; break;
  565. case 'f': fmt_precision = 6; break;
  566. case 'v': fmt_precision = 1; break;
  567. }
  568. // built the format string
  569. new_format_i = 0;
  570. new_format[new_format_i++] = '%';
  571. if (fmt_leadzero) new_format[new_format_i++] = '0';
  572. if (fmt_leftjust) new_format[new_format_i++] = '-';
  573. if (fmt_signed) new_format[new_format_i++] = '+';
  574. if (fmt_space) new_format[new_format_i++] = ' ';
  575. if (fmt_alternate) new_format[new_format_i++] = '#';
  576. if (fmt_minwidth)
  577. if ((new_format_i += snprintf (new_format + new_format_i,
  578. sizeof (new_format) -
  579. new_format_i,
  580. "%d", fmt_minwidth))
  581. >= sizeof (new_format))
  582. PR_Error (pr, "PF_sprintf: new_format overflowed?!");
  583. if (fmt_type != 'i') {
  584. new_format[new_format_i++] = '.';
  585. if ((new_format_i += snprintf (new_format + new_format_i,
  586. sizeof (new_format)
  587. - new_format_i,
  588. "%d", fmt_precision))
  589. >= sizeof (new_format))
  590. PR_Error (pr, "PF_sprintf: new_format overflowed?!");
  591. }
  592. switch (fmt_type) {
  593. case 'i': new_format[new_format_i++] = 'd'; break;
  594. case 'f':
  595. case 'v': new_format[new_format_i++] = 'f'; break;
  596. default: PR_Error (pr, "PF_sprintf: unknown type '%c'!", *c);
  597. }
  598. new_format[new_format_i++] = '\0';
  599. switch (fmt_type) {
  600. case 'i':
  601. while ((ret = snprintf (&out[out_size], out_max - out_size,
  602. new_format,
  603. P_INT (pr, 0 + curarg)))
  604. >= out_max - out_size) {
  605. char *o;
  606. out_max *= 2;
  607. o = realloc (out, out_max);
  608. if (!o)
  609. goto mallocerror;
  610. out = o;
  611. }
  612. out_size += ret;
  613. curarg += 3;
  614. break;
  615. case 'f':
  616. while ((ret = snprintf (&out[out_size], out_max - out_size,
  617. new_format,
  618. P_FLOAT (pr, 0 + curarg)))
  619. >= out_max - out_size) {
  620. char *o;
  621. out_max *= 2;
  622. o = realloc (out, out_max);
  623. if (!o)
  624. goto mallocerror;
  625. out = o;
  626. }
  627. out_size += ret;
  628. curarg += 3;
  629. break;
  630. case 'v': {
  631. int i;
  632. for (i = 0; i <= 2; i++) {
  633. if (curarg > MAX_ARG)
  634. goto maxargs;
  635. while ((ret = snprintf (&out[out_size],
  636. out_max - out_size, new_format,
  637. P_FLOAT (pr, 0 +
  638. curarg)))
  639. >= out_max - out_size) {
  640. char *o;
  641. out_max *= 2;
  642. o = realloc (out, out_max);
  643. if (!o)
  644. goto mallocerror;
  645. out = o;
  646. }
  647. out_size += ret;
  648. curarg++;
  649. i++;
  650. }
  651. break;
  652. }
  653. }
  654. } else if (*c == '%' && *(c + 1) == 's') {
  655. char *s;
  656. if (curarg > MAX_ARG)
  657. goto maxargs;
  658. s = P_STRING (pr, 0 + curarg);
  659. while ((ret = snprintf (&out[out_size], out_max - out_size, "%s",
  660. s))
  661. >= out_max - out_size) {
  662. char *o;
  663. out_max *= 2;
  664. o = realloc (out, out_max);
  665. if (!o)
  666. goto mallocerror;
  667. out = o;
  668. }
  669. out_size += ret;
  670. curarg += 3;
  671. c += 2;
  672. } else {
  673. if (*c == '%')
  674. c++;
  675. if (out_size == out_max) {
  676. char *o;
  677. out_max *= 2;
  678. o = realloc (out, out_max);
  679. if (!o)
  680. goto mallocerror;
  681. out = o;
  682. }
  683. out[out_size] = *c;
  684. out_size++;
  685. c++;
  686. }
  687. }
  688. if (out_size == out_max) {
  689. char *o;
  690. out_max *= 2;
  691. o = realloc (out, out_max);
  692. if (!o)
  693. goto mallocerror;
  694. out = o;
  695. }
  696. out[out_size] = '\0';
  697. RETURN_STRING (pr, out);
  698. free (out);
  699. return;
  700. mallocerror:
  701. // if (errno == ENOMEM)
  702. // hopefully we can free up some mem so it can be used during shutdown
  703. // free (out);
  704. PR_Error (pr, "PF_sprintf: memory allocation error!\n");
  705. endofstring:
  706. PR_Error (pr, "PF_sprintf: unexpected end of string!\n");
  707. maxargs:
  708. PR_Error (pr, "PF_sprintf: argument limit exceeded\n");
  709. }
  710. void
  711. PR_gametype (progs_t *pr)
  712. {
  713. RETURN_STRING (pr, pr_gametype);
  714. }
  715. void
  716. PR_Cmds_Init (progs_t *pr)
  717. {
  718. PR_AddBuiltin (pr, "break", PF_break, 6); // void () break
  719. PR_AddBuiltin (pr, "random", PF_random, 7); // float () random
  720. PR_AddBuiltin (pr, "normalize", PF_normalize, 9); // vector (vector v) normalize
  721. PR_AddBuiltin (pr, "vlen", PF_vlen, 12); // float (vector v) vlen
  722. PR_AddBuiltin (pr, "vectoyaw", PF_vectoyaw, 13); // float (vector v) vectoyaw
  723. PR_AddBuiltin (pr, "find", PF_Find, 18); // entity (entity start, .(...) fld, ... match) find
  724. PR_AddBuiltin (pr, "dprint", PF_dprint, 25); // void (string s) dprint
  725. PR_AddBuiltin (pr, "coredump", PF_coredump, 28); // void () coredump
  726. PR_AddBuiltin (pr, "traceon", PF_traceon, 29); // void () traceon
  727. PR_AddBuiltin (pr, "traceoff", PF_traceoff, 30); // void () traceoff
  728. PR_AddBuiltin (pr, "eprint", PF_eprint, 31); // void (entity e) eprint
  729. PR_AddBuiltin (pr, "rint", PF_rint, 36); // float (float v) rint
  730. PR_AddBuiltin (pr, "floor", PF_floor, 37); // float (float v) floor
  731. PR_AddBuiltin (pr, "ceil", PF_ceil, 38); // float (float v) ceil
  732. PR_AddBuiltin (pr, "fabs", PF_fabs, 43); // float (float f) fabs
  733. PR_AddBuiltin (pr, "cvar", PF_cvar, 45); // float (string s) cvar
  734. #if 0
  735. PR_AddBuiltin (pr, "localcmd", PF_localcmd, 46); // void (string s) localcmd
  736. #endif
  737. PR_AddBuiltin (pr, "nextent", PF_nextent, 47); // entity (entity e) nextent
  738. PR_AddBuiltin (pr, "vectoangles", PF_vectoangles, 51); // vector (vector v) vectoangles
  739. PR_AddBuiltin (pr, "cvar_set", PF_cvar_set, 72); // void (string var, string val) cvar_set
  740. PR_AddBuiltin (pr, "strlen", PF_strlen, 100); // float (string s) strlen
  741. PR_AddBuiltin (pr, "charcount", PF_charcount, 101); // float (string goal, string s) charcount
  742. PR_AddBuiltin (pr, "sprintf", PF_sprintf, 109); // string (...) sprintf
  743. PR_AddBuiltin (pr, "ftos", PF_ftos, 26); // string (float f) ftos
  744. PR_AddBuiltin (pr, "ftoi", PF_ftoi, 110); // integer (float f) ftoi
  745. PR_AddBuiltin (pr, "itof", PF_itof, 111); // float (integer i) itof
  746. PR_AddBuiltin (pr, "itos", PF_itos, 112); // string (integer i) itos
  747. PR_AddBuiltin (pr, "stof", PF_stof, 81); // float (string s) stof
  748. PR_AddBuiltin (pr, "stoi", PF_stoi, 113); // integer (string s) stoi
  749. PR_AddBuiltin (pr, "stov", PF_stov, 114); // vector (string s) stov
  750. PR_AddBuiltin (pr, "vtos", PF_vtos, 27); // string (vector v) vtos
  751. PR_AddBuiltin (pr, "gametype", PR_gametype, 115); // string () gametype
  752. };