1 /* 2 Copyright (C) 1996-1997 Id Software, Inc. 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 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 13 See the GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 */ 20 // sv_edict.c -- entity dictionary 21 22 #include "qwsvdef.h" 23 24 dprograms_t *progs; 25 dfunction_t *pr_functions; 26 char *pr_strings; 27 ddef_t *pr_fielddefs; 28 ddef_t *pr_globaldefs; 29 dstatement_t *pr_statements; 30 globalvars_t *pr_global_struct; 31 float *pr_globals; // same as pr_global_struct 32 int pr_edict_size; // in bytes 33 34 int type_size[8] = {1,sizeof(void *)/4,1,3,1,1,sizeof(void *)/4,sizeof(void *)/4}; 35 36 ddef_t *ED_FieldAtOfs (int ofs); 37 qboolean ED_ParseEpair (void *base, ddef_t *key, char *s); 38 39 #define MAX_FIELD_LEN 64 40 #define GEFV_CACHESIZE 2 41 42 typedef struct { 43 ddef_t *pcache; 44 char field[MAX_FIELD_LEN]; 45 } gefv_cache; 46 47 static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}}; 48 49 func_t SpectatorConnect; 50 func_t SpectatorThink; 51 func_t SpectatorDisconnect; 52 53 54 /* 55 ================= 56 ED_ClearEdict 57 58 Sets everything to NULL 59 ================= 60 */ 61 void ED_ClearEdict (edict_t *e) 62 { 63 memset (&e->v, 0, progs->entityfields * 4); 64 e->free = false; 65 } 66 67 /* 68 ================= 69 ED_Alloc 70 71 Either finds a free edict, or allocates a new one. 72 Try to avoid reusing an entity that was recently freed, because it 73 can cause the client to think the entity morphed into something else 74 instead of being removed and recreated, which can cause interpolated 75 angles and bad trails. 76 ================= 77 */ 78 edict_t *ED_Alloc (void) 79 { 80 int i; 81 edict_t *e; 82 83 for ( i=MAX_CLIENTS+1 ; i<sv.num_edicts ; i++) 84 { 85 e = EDICT_NUM(i); 86 // the first couple seconds of server time can involve a lot of 87 // freeing and allocating, so relax the replacement policy 88 if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) ) 89 { 90 ED_ClearEdict (e); 91 return e; 92 } 93 } 94 95 if (i == MAX_EDICTS) 96 { 97 Con_Printf ("WARNING: ED_Alloc: no free edicts\n"); 98 i--; // step on whatever is the last edict 99 e = EDICT_NUM(i); 100 SV_UnlinkEdict(e); 101 } 102 else 103 sv.num_edicts++; 104 e = EDICT_NUM(i); 105 ED_ClearEdict (e); 106 107 return e; 108 } 109 110 /* 111 ================= 112 ED_Free 113 114 Marks the edict as free 115 FIXME: walk all entities and NULL out references to this entity 116 ================= 117 */ 118 void ED_Free (edict_t *ed) 119 { 120 SV_UnlinkEdict (ed); // unlink from world bsp 121 122 ed->free = true; 123 ed->v.model = 0; 124 ed->v.takedamage = 0; 125 ed->v.modelindex = 0; 126 ed->v.colormap = 0; 127 ed->v.skin = 0; 128 ed->v.frame = 0; 129 VectorCopy (vec3_origin, ed->v.origin); 130 VectorCopy (vec3_origin, ed->v.angles); 131 ed->v.nextthink = -1; 132 ed->v.solid = 0; 133 134 ed->freetime = sv.time; 135 } 136 137 //=========================================================================== 138 139 /* 140 ============ 141 ED_GlobalAtOfs 142 ============ 143 */ 144 ddef_t *ED_GlobalAtOfs (int ofs) 145 { 146 ddef_t *def; 147 int i; 148 149 for (i=0 ; i<progs->numglobaldefs ; i++) 150 { 151 def = &pr_globaldefs[i]; 152 if (def->ofs == ofs) 153 return def; 154 } 155 return NULL; 156 } 157 158 /* 159 ============ 160 ED_FieldAtOfs 161 ============ 162 */ 163 ddef_t *ED_FieldAtOfs (int ofs) 164 { 165 ddef_t *def; 166 int i; 167 168 for (i=0 ; i<progs->numfielddefs ; i++) 169 { 170 def = &pr_fielddefs[i]; 171 if (def->ofs == ofs) 172 return def; 173 } 174 return NULL; 175 } 176 177 /* 178 ============ 179 ED_FindField 180 ============ 181 */ 182 ddef_t *ED_FindField (char *name) 183 { 184 ddef_t *def; 185 int i; 186 187 for (i=0 ; i<progs->numfielddefs ; i++) 188 { 189 def = &pr_fielddefs[i]; 190 if (!strcmp(PR_GetString(def->s_name),name) ) 191 return def; 192 } 193 return NULL; 194 } 195 196 197 /* 198 ============ 199 ED_FindGlobal 200 ============ 201 */ 202 ddef_t *ED_FindGlobal (char *name) 203 { 204 ddef_t *def; 205 int i; 206 207 for (i=0 ; i<progs->numglobaldefs ; i++) 208 { 209 def = &pr_globaldefs[i]; 210 if (!strcmp(PR_GetString(def->s_name),name) ) 211 return def; 212 } 213 return NULL; 214 } 215 216 217 /* 218 ============ 219 ED_FindFunction 220 ============ 221 */ 222 dfunction_t *ED_FindFunction (char *name) 223 { 224 dfunction_t *func; 225 int i; 226 227 for (i=0 ; i<progs->numfunctions ; i++) 228 { 229 func = &pr_functions[i]; 230 if (!strcmp(PR_GetString(func->s_name),name) ) 231 return func; 232 } 233 return NULL; 234 } 235 236 eval_t *GetEdictFieldValue(edict_t *ed, char *field) 237 { 238 ddef_t *def = NULL; 239 int i; 240 static int rep = 0; 241 242 for (i=0 ; i<GEFV_CACHESIZE ; i++) 243 { 244 if (!strcmp(field, gefvCache[i].field)) 245 { 246 def = gefvCache[i].pcache; 247 goto Done; 248 } 249 } 250 251 def = ED_FindField (field); 252 253 if (strlen(field) < MAX_FIELD_LEN) 254 { 255 gefvCache[rep].pcache = def; 256 strcpy (gefvCache[rep].field, field); 257 rep ^= 1; 258 } 259 260 Done: 261 if (!def) 262 return NULL; 263 264 return (eval_t *)((char *)&ed->v + def->ofs*4); 265 } 266 267 /* 268 ============ 269 PR_ValueString 270 271 Returns a string describing *data in a type specific manner 272 ============= 273 */ 274 char *PR_ValueString (etype_t type, eval_t *val) 275 { 276 static char line[256]; 277 ddef_t *def; 278 dfunction_t *f; 279 280 type &= ~DEF_SAVEGLOBAL; 281 282 switch (type) 283 { 284 case ev_string: 285 sprintf (line, "%s", PR_GetString(val->string)); 286 break; 287 case ev_entity: 288 sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) ); 289 break; 290 case ev_function: 291 f = pr_functions + val->function; 292 sprintf (line, "%s()", PR_GetString(f->s_name)); 293 break; 294 case ev_field: 295 def = ED_FieldAtOfs ( val->_int ); 296 sprintf (line, ".%s", PR_GetString(def->s_name)); 297 break; 298 case ev_void: 299 sprintf (line, "void"); 300 break; 301 case ev_float: 302 sprintf (line, "%5.1f", val->_float); 303 break; 304 case ev_vector: 305 sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]); 306 break; 307 case ev_pointer: 308 sprintf (line, "pointer"); 309 break; 310 default: 311 sprintf (line, "bad type %i", type); 312 break; 313 } 314 315 return line; 316 } 317 318 /* 319 ============ 320 PR_UglyValueString 321 322 Returns a string describing *data in a type specific manner 323 Easier to parse than PR_ValueString 324 ============= 325 */ 326 char *PR_UglyValueString (etype_t type, eval_t *val) 327 { 328 static char line[256]; 329 ddef_t *def; 330 dfunction_t *f; 331 332 type &= ~DEF_SAVEGLOBAL; 333 334 switch (type) 335 { 336 case ev_string: 337 sprintf (line, "%s", PR_GetString(val->string)); 338 break; 339 case ev_entity: 340 sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict))); 341 break; 342 case ev_function: 343 f = pr_functions + val->function; 344 sprintf (line, "%s", PR_GetString(f->s_name)); 345 break; 346 case ev_field: 347 def = ED_FieldAtOfs ( val->_int ); 348 sprintf (line, "%s", PR_GetString(def->s_name)); 349 break; 350 case ev_void: 351 sprintf (line, "void"); 352 break; 353 case ev_float: 354 sprintf (line, "%f", val->_float); 355 break; 356 case ev_vector: 357 sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); 358 break; 359 default: 360 sprintf (line, "bad type %i", type); 361 break; 362 } 363 364 return line; 365 } 366 367 /* 368 ============ 369 PR_GlobalString 370 371 Returns a string with a description and the contents of a global, 372 padded to 20 field width 373 ============ 374 */ 375 char *PR_GlobalString (int ofs) 376 { 377 char *s; 378 int i; 379 ddef_t *def; 380 void *val; 381 static char line[128]; 382 383 val = (void *)&pr_globals[ofs]; 384 def = ED_GlobalAtOfs(ofs); 385 if (!def) 386 sprintf (line,"%i(???)", ofs); 387 else 388 { 389 s = PR_ValueString (def->type, val); 390 sprintf (line,"%i(%s)%s", ofs, PR_GetString(def->s_name), s); 391 } 392 393 i = strlen(line); 394 for ( ; i<20 ; i++) 395 strcat (line," "); 396 strcat (line," "); 397 398 return line; 399 } 400 401 char *PR_GlobalStringNoContents (int ofs) 402 { 403 int i; 404 ddef_t *def; 405 static char line[128]; 406 407 def = ED_GlobalAtOfs(ofs); 408 if (!def) 409 sprintf (line,"%i(???)", ofs); 410 else 411 sprintf (line,"%i(%s)", ofs, PR_GetString(def->s_name)); 412 413 i = strlen(line); 414 for ( ; i<20 ; i++) 415 strcat (line," "); 416 strcat (line," "); 417 418 return line; 419 } 420 421 422 /* 423 ============= 424 ED_Print 425 426 For debugging 427 ============= 428 */ 429 void ED_Print (edict_t *ed) 430 { 431 int l; 432 ddef_t *d; 433 int *v; 434 int i, j; 435 char *name; 436 int type; 437 438 if (ed->free) 439 { 440 Con_Printf ("FREE\n"); 441 return; 442 } 443 444 for (i=1 ; i<progs->numfielddefs ; i++) 445 { 446 d = &pr_fielddefs[i]; 447 name = PR_GetString(d->s_name); 448 if (name[strlen(name)-2] == '_') 449 continue; // skip _x, _y, _z vars 450 451 v = (int *)((char *)&ed->v + d->ofs*4); 452 453 // if the value is still all 0, skip the field 454 type = d->type & ~DEF_SAVEGLOBAL; 455 456 for (j=0 ; j<type_size[type] ; j++) 457 if (v[j]) 458 break; 459 if (j == type_size[type]) 460 continue; 461 462 Con_Printf ("%s",name); 463 l = strlen (name); 464 while (l++ < 15) 465 Con_Printf (" "); 466 467 Con_Printf ("%s\n", PR_ValueString(d->type, (eval_t *)v)); 468 } 469 } 470 471 /* 472 ============= 473 ED_Write 474 475 For savegames 476 ============= 477 */ 478 void ED_Write (FILE *f, edict_t *ed) 479 { 480 ddef_t *d; 481 int *v; 482 int i, j; 483 char *name; 484 int type; 485 486 fprintf (f, "{\n"); 487 488 if (ed->free) 489 { 490 fprintf (f, "}\n"); 491 return; 492 } 493 494 for (i=1 ; i<progs->numfielddefs ; i++) 495 { 496 d = &pr_fielddefs[i]; 497 name = PR_GetString(d->s_name); 498 if (name[strlen(name)-2] == '_') 499 continue; // skip _x, _y, _z vars 500 501 v = (int *)((char *)&ed->v + d->ofs*4); 502 503 // if the value is still all 0, skip the field 504 type = d->type & ~DEF_SAVEGLOBAL; 505 for (j=0 ; j<type_size[type] ; j++) 506 if (v[j]) 507 break; 508 if (j == type_size[type]) 509 continue; 510 511 fprintf (f,"\"%s\" ",name); 512 fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v)); 513 } 514 515 fprintf (f, "}\n"); 516 } 517 518 void ED_PrintNum (int ent) 519 { 520 ED_Print (EDICT_NUM(ent)); 521 } 522 523 /* 524 ============= 525 ED_PrintEdicts 526 527 For debugging, prints all the entities in the current server 528 ============= 529 */ 530 void ED_PrintEdicts (void) 531 { 532 int i; 533 534 Con_Printf ("%i entities\n", sv.num_edicts); 535 for (i=0 ; i<sv.num_edicts ; i++) 536 { 537 Con_Printf ("\nEDICT %i:\n",i); 538 ED_PrintNum (i); 539 } 540 } 541 542 /* 543 ============= 544 ED_PrintEdict_f 545 546 For debugging, prints a single edicy 547 ============= 548 */ 549 void ED_PrintEdict_f (void) 550 { 551 int i; 552 553 i = Q_atoi (Cmd_Argv(1)); 554 Con_Printf ("\n EDICT %i:\n",i); 555 ED_PrintNum (i); 556 } 557 558 /* 559 ============= 560 ED_Count 561 562 For debugging 563 ============= 564 */ 565 void ED_Count (void) 566 { 567 int i; 568 edict_t *ent; 569 int active, models, solid, step; 570 571 active = models = solid = step = 0; 572 for (i=0 ; i<sv.num_edicts ; i++) 573 { 574 ent = EDICT_NUM(i); 575 if (ent->free) 576 continue; 577 active++; 578 if (ent->v.solid) 579 solid++; 580 if (ent->v.model) 581 models++; 582 if (ent->v.movetype == MOVETYPE_STEP) 583 step++; 584 } 585 586 Con_Printf ("num_edicts:%3i\n", sv.num_edicts); 587 Con_Printf ("active :%3i\n", active); 588 Con_Printf ("view :%3i\n", models); 589 Con_Printf ("touch :%3i\n", solid); 590 Con_Printf ("step :%3i\n", step); 591 592 } 593 594 /* 595 ============================================================================== 596 597 ARCHIVING GLOBALS 598 599 FIXME: need to tag constants, doesn't really work 600 ============================================================================== 601 */ 602 603 /* 604 ============= 605 ED_WriteGlobals 606 ============= 607 */ 608 void ED_WriteGlobals (FILE *f) 609 { 610 ddef_t *def; 611 int i; 612 char *name; 613 int type; 614 615 fprintf (f,"{\n"); 616 for (i=0 ; i<progs->numglobaldefs ; i++) 617 { 618 def = &pr_globaldefs[i]; 619 type = def->type; 620 if ( !(def->type & DEF_SAVEGLOBAL) ) 621 continue; 622 type &= ~DEF_SAVEGLOBAL; 623 624 if (type != ev_string 625 && type != ev_float 626 && type != ev_entity) 627 continue; 628 629 name = PR_GetString(def->s_name); 630 fprintf (f,"\"%s\" ", name); 631 fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs])); 632 } 633 fprintf (f,"}\n"); 634 } 635 636 /* 637 ============= 638 ED_ParseGlobals 639 ============= 640 */ 641 void ED_ParseGlobals (char *data) 642 { 643 char keyname[64]; 644 ddef_t *key; 645 646 while (1) 647 { 648 // parse key 649 data = COM_Parse (data); 650 if (com_token[0] == '}') 651 break; 652 if (!data) 653 SV_Error ("ED_ParseEntity: EOF without closing brace"); 654 655 strcpy (keyname, com_token); 656 657 // parse value 658 data = COM_Parse (data); 659 if (!data) 660 SV_Error ("ED_ParseEntity: EOF without closing brace"); 661 662 if (com_token[0] == '}') 663 SV_Error ("ED_ParseEntity: closing brace without data"); 664 665 key = ED_FindGlobal (keyname); 666 if (!key) 667 { 668 Con_Printf ("%s is not a global\n", keyname); 669 continue; 670 } 671 672 if (!ED_ParseEpair ((void *)pr_globals, key, com_token)) 673 SV_Error ("ED_ParseGlobals: parse error"); 674 } 675 } 676 677 //============================================================================ 678 679 680 /* 681 ============= 682 ED_NewString 683 ============= 684 */ 685 char *ED_NewString (char *string) 686 { 687 char *new, *new_p; 688 int i,l; 689 690 l = strlen(string) + 1; 691 new = Hunk_Alloc (l); 692 new_p = new; 693 694 for (i=0 ; i< l ; i++) 695 { 696 if (string[i] == '\\' && i < l-1) 697 { 698 i++; 699 if (string[i] == 'n') 700 *new_p++ = '\n'; 701 else 702 *new_p++ = '\\'; 703 } 704 else 705 *new_p++ = string[i]; 706 } 707 708 return new; 709 } 710 711 712 /* 713 ============= 714 ED_ParseEval 715 716 Can parse either fields or globals 717 returns false if error 718 ============= 719 */ 720 qboolean ED_ParseEpair (void *base, ddef_t *key, char *s) 721 { 722 int i; 723 char string[128]; 724 ddef_t *def; 725 char *v, *w; 726 void *d; 727 dfunction_t *func; 728 729 d = (void *)((int *)base + key->ofs); 730 731 switch (key->type & ~DEF_SAVEGLOBAL) 732 { 733 case ev_string: 734 *(string_t *)d = PR_SetString(ED_NewString (s)); 735 break; 736 737 case ev_float: 738 *(float *)d = atof (s); 739 break; 740 741 case ev_vector: 742 strcpy (string, s); 743 v = string; 744 w = string; 745 for (i=0 ; i<3 ; i++) 746 { 747 while (*v && *v != ' ') 748 v++; 749 *v = 0; 750 ((float *)d)[i] = atof (w); 751 w = v = v+1; 752 } 753 break; 754 755 case ev_entity: 756 *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s))); 757 break; 758 759 case ev_field: 760 def = ED_FindField (s); 761 if (!def) 762 { 763 Con_Printf ("Can't find field %s\n", s); 764 return false; 765 } 766 *(int *)d = G_INT(def->ofs); 767 break; 768 769 case ev_function: 770 func = ED_FindFunction (s); 771 if (!func) 772 { 773 Con_Printf ("Can't find function %s\n", s); 774 return false; 775 } 776 *(func_t *)d = func - pr_functions; 777 break; 778 779 default: 780 break; 781 } 782 return true; 783 } 784 785 /* 786 ==================== 787 ED_ParseEdict 788 789 Parses an edict out of the given string, returning the new position 790 ed should be a properly initialized empty edict. 791 Used for initial level load and for savegames. 792 ==================== 793 */ 794 char *ED_ParseEdict (char *data, edict_t *ent) 795 { 796 ddef_t *key; 797 qboolean anglehack; 798 qboolean init; 799 char keyname[256]; 800 801 init = false; 802 803 // clear it 804 if (ent != sv.edicts) // hack 805 memset (&ent->v, 0, progs->entityfields * 4); 806 807 // go through all the dictionary pairs 808 while (1) 809 { 810 // parse key 811 data = COM_Parse (data); 812 if (com_token[0] == '}') 813 break; 814 if (!data) 815 SV_Error ("ED_ParseEntity: EOF without closing brace"); 816 817 // anglehack is to allow QuakeEd to write single scalar angles 818 // and allow them to be turned into vectors. (FIXME...) 819 if (!strcmp(com_token, "angle")) 820 { 821 strcpy (com_token, "angles"); 822 anglehack = true; 823 } 824 else 825 anglehack = false; 826 827 // FIXME: change light to _light to get rid of this hack 828 if (!strcmp(com_token, "light")) 829 strcpy (com_token, "light_lev"); // hack for single light def 830 831 strcpy (keyname, com_token); 832 833 // parse value 834 data = COM_Parse (data); 835 if (!data) 836 SV_Error ("ED_ParseEntity: EOF without closing brace"); 837 838 if (com_token[0] == '}') 839 SV_Error ("ED_ParseEntity: closing brace without data"); 840 841 init = true; 842 843 // keynames with a leading underscore are used for utility comments, 844 // and are immediately discarded by quake 845 if (keyname[0] == '_') 846 continue; 847 848 key = ED_FindField (keyname); 849 if (!key) 850 { 851 Con_Printf ("%s is not a field\n", keyname); 852 continue; 853 } 854 855 if (anglehack) 856 { 857 char temp[32]; 858 strcpy (temp, com_token); 859 sprintf (com_token, "0 %s 0", temp); 860 } 861 862 if (!ED_ParseEpair ((void *)&ent->v, key, com_token)) 863 SV_Error ("ED_ParseEdict: parse error"); 864 } 865 866 if (!init) 867 ent->free = true; 868 869 return data; 870 } 871 872 873 /* 874 ================ 875 ED_LoadFromFile 876 877 The entities are directly placed in the array, rather than allocated with 878 ED_Alloc, because otherwise an error loading the map would have entity 879 number references out of order. 880 881 Creates a server's entity / program execution context by 882 parsing textual entity definitions out of an ent file. 883 884 Used for both fresh maps and savegame loads. A fresh map would also need 885 to call ED_CallSpawnFunctions () to let the objects initialize themselves. 886 ================ 887 */ 888 void ED_LoadFromFile (char *data) 889 { 890 edict_t *ent; 891 int inhibit; 892 dfunction_t *func; 893 894 ent = NULL; 895 inhibit = 0; 896 pr_global_struct->time = sv.time; 897 898 // parse ents 899 while (1) 900 { 901 // parse the opening brace 902 data = COM_Parse (data); 903 if (!data) 904 break; 905 if (com_token[0] != '{') 906 SV_Error ("ED_LoadFromFile: found %s when expecting {",com_token); 907 908 if (!ent) 909 ent = EDICT_NUM(0); 910 else 911 ent = ED_Alloc (); 912 data = ED_ParseEdict (data, ent); 913 914 // remove things from different skill levels or deathmatch 915 if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) 916 { 917 ED_Free (ent); 918 inhibit++; 919 continue; 920 } 921 922 // 923 // immediately call spawn function 924 // 925 if (!ent->v.classname) 926 { 927 Con_Printf ("No classname for:\n"); 928 ED_Print (ent); 929 ED_Free (ent); 930 continue; 931 } 932 933 // look for the spawn function 934 func = ED_FindFunction ( PR_GetString(ent->v.classname) ); 935 936 if (!func) 937 { 938 Con_Printf ("No spawn function for:\n"); 939 ED_Print (ent); 940 ED_Free (ent); 941 continue; 942 } 943 944 pr_global_struct->self = EDICT_TO_PROG(ent); 945 PR_ExecuteProgram (func - pr_functions); 946 SV_FlushSignon(); 947 } 948 949 Con_DPrintf ("%i entities inhibited\n", inhibit); 950 } 951 952 953 /* 954 =============== 955 PR_LoadProgs 956 =============== 957 */ 958 void PR_LoadProgs (void) 959 { 960 int i; 961 char num[32]; 962 dfunction_t *f; 963 964 // flush the non-C variable lookup cache 965 for (i=0 ; i<GEFV_CACHESIZE ; i++) 966 gefvCache[i].field[0] = 0; 967 968 progs = (dprograms_t *)COM_LoadHunkFile ("qwprogs.dat"); 969 if (!progs) 970 progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat"); 971 if (!progs) 972 SV_Error ("PR_LoadProgs: couldn't load progs.dat"); 973 Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024); 974 975 // add prog crc to the serverinfo 976 sprintf (num, "%i", CRC_Block ((byte *)progs, com_filesize)); 977 Info_SetValueForStarKey (svs.info, "*progs", num, MAX_SERVERINFO_STRING); 978 979 // byte swap the header 980 for (i=0 ; i<sizeof(*progs)/4 ; i++) 981 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] ); 982 983 if (progs->version != PROG_VERSION) 984 SV_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); 985 if (progs->crc != PROGHEADER_CRC) 986 SV_Error ("You must have the progs.dat from QuakeWorld installed"); 987 988 pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions); 989 pr_strings = (char *)progs + progs->ofs_strings; 990 pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs); 991 pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs); 992 pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements); 993 994 num_prstr = 0; 995 996 pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals); 997 pr_globals = (float *)pr_global_struct; 998 999 pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t); 1000 1001 // byte swap the lumps 1002 for (i=0 ; i<progs->numstatements ; i++) 1003 { 1004 pr_statements[i].op = LittleShort(pr_statements[i].op); 1005 pr_statements[i].a = LittleShort(pr_statements[i].a); 1006 pr_statements[i].b = LittleShort(pr_statements[i].b); 1007 pr_statements[i].c = LittleShort(pr_statements[i].c); 1008 } 1009 1010 for (i=0 ; i<progs->numfunctions; i++) 1011 { 1012 pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement); 1013 pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); 1014 pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); 1015 pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); 1016 pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); 1017 pr_functions[i].locals = LittleLong (pr_functions[i].locals); 1018 } 1019 1020 for (i=0 ; i<progs->numglobaldefs ; i++) 1021 { 1022 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type); 1023 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs); 1024 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name); 1025 } 1026 1027 for (i=0 ; i<progs->numfielddefs ; i++) 1028 { 1029 pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type); 1030 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL) 1031 SV_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); 1032 pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); 1033 pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); 1034 } 1035 1036 for (i=0 ; i<progs->numglobals ; i++) 1037 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); 1038 1039 // Zoid, find the spectator functions 1040 SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0; 1041 1042 if ((f = ED_FindFunction ("SpectatorConnect")) != NULL) 1043 SpectatorConnect = (func_t)(f - pr_functions); 1044 if ((f = ED_FindFunction ("SpectatorThink")) != NULL) 1045 SpectatorThink = (func_t)(f - pr_functions); 1046 if ((f = ED_FindFunction ("SpectatorDisconnect")) != NULL) 1047 SpectatorDisconnect = (func_t)(f - pr_functions); 1048 } 1049 1050 1051 /* 1052 =============== 1053 PR_Init 1054 =============== 1055 */ 1056 void PR_Init (void) 1057 { 1058 Cmd_AddCommand ("edict", ED_PrintEdict_f); 1059 Cmd_AddCommand ("edicts", ED_PrintEdicts); 1060 Cmd_AddCommand ("edictcount", ED_Count); 1061 Cmd_AddCommand ("profile", PR_Profile_f); 1062 } 1063 1064 1065 1066 edict_t *EDICT_NUM(int n) 1067 { 1068 if (n < 0 || n >= MAX_EDICTS) 1069 SV_Error ("EDICT_NUM: bad number %i", n); 1070 return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size); 1071 } 1072 1073 int NUM_FOR_EDICT(edict_t *e) 1074 { 1075 int b; 1076 1077 b = (byte *)e - (byte *)sv.edicts; 1078 b = b / pr_edict_size; 1079 1080 if (b < 0 || b >= sv.num_edicts) 1081 SV_Error ("NUM_FOR_EDICT: bad pointer"); 1082 return b; 1083 } 1084 1085 1086