common.c (34055B)
1 /* 2 Copyright (C) 1997-2001 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 // common.c -- misc functions used in client and server 21 #include "qcommon.h" 22 #include <setjmp.h> 23 24 #define MAXPRINTMSG 4096 25 26 #define MAX_NUM_ARGVS 50 27 28 29 int com_argc; 30 char *com_argv[MAX_NUM_ARGVS+1]; 31 32 int realtime; 33 34 jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame 35 36 37 FILE *log_stats_file; 38 39 cvar_t *host_speeds; 40 cvar_t *log_stats; 41 cvar_t *developer; 42 cvar_t *timescale; 43 cvar_t *fixedtime; 44 cvar_t *logfile_active; // 1 = buffer log, 2 = flush after each print 45 cvar_t *showtrace; 46 cvar_t *dedicated; 47 48 FILE *logfile; 49 50 int server_state; 51 52 // host_speeds times 53 int time_before_game; 54 int time_after_game; 55 int time_before_ref; 56 int time_after_ref; 57 58 /* 59 ============================================================================ 60 61 CLIENT / SERVER interactions 62 63 ============================================================================ 64 */ 65 66 static int rd_target; 67 static char *rd_buffer; 68 static int rd_buffersize; 69 static void (*rd_flush)(int target, char *buffer); 70 71 void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush)) 72 { 73 if (!target || !buffer || !buffersize || !flush) 74 return; 75 rd_target = target; 76 rd_buffer = buffer; 77 rd_buffersize = buffersize; 78 rd_flush = flush; 79 80 *rd_buffer = 0; 81 } 82 83 void Com_EndRedirect (void) 84 { 85 rd_flush(rd_target, rd_buffer); 86 87 rd_target = 0; 88 rd_buffer = NULL; 89 rd_buffersize = 0; 90 rd_flush = NULL; 91 } 92 93 /* 94 ============= 95 Com_Printf 96 97 Both client and server can use this, and it will output 98 to the apropriate place. 99 ============= 100 */ 101 void Com_Printf (char *fmt, ...) 102 { 103 va_list argptr; 104 char msg[MAXPRINTMSG]; 105 106 va_start (argptr,fmt); 107 vsprintf (msg,fmt,argptr); 108 va_end (argptr); 109 110 if (rd_target) 111 { 112 if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) 113 { 114 rd_flush(rd_target, rd_buffer); 115 *rd_buffer = 0; 116 } 117 strcat (rd_buffer, msg); 118 return; 119 } 120 121 Con_Print (msg); 122 123 // also echo to debugging console 124 Sys_ConsoleOutput (msg); 125 126 // logfile 127 if (logfile_active && logfile_active->value) 128 { 129 char name[MAX_QPATH]; 130 131 if (!logfile) 132 { 133 Com_sprintf (name, sizeof(name), "%s/qconsole.log", FS_Gamedir ()); 134 logfile = fopen (name, "w"); 135 } 136 if (logfile) 137 fprintf (logfile, "%s", msg); 138 if (logfile_active->value > 1) 139 fflush (logfile); // force it to save every time 140 } 141 } 142 143 144 /* 145 ================ 146 Com_DPrintf 147 148 A Com_Printf that only shows up if the "developer" cvar is set 149 ================ 150 */ 151 void Com_DPrintf (char *fmt, ...) 152 { 153 va_list argptr; 154 char msg[MAXPRINTMSG]; 155 156 if (!developer || !developer->value) 157 return; // don't confuse non-developers with techie stuff... 158 159 va_start (argptr,fmt); 160 vsprintf (msg,fmt,argptr); 161 va_end (argptr); 162 163 Com_Printf ("%s", msg); 164 } 165 166 167 /* 168 ============= 169 Com_Error 170 171 Both client and server can use this, and it will 172 do the apropriate things. 173 ============= 174 */ 175 void Com_Error (int code, char *fmt, ...) 176 { 177 va_list argptr; 178 static char msg[MAXPRINTMSG]; 179 static qboolean recursive; 180 181 if (recursive) 182 Sys_Error ("recursive error after: %s", msg); 183 recursive = true; 184 185 va_start (argptr,fmt); 186 vsprintf (msg,fmt,argptr); 187 va_end (argptr); 188 189 if (code == ERR_DISCONNECT) 190 { 191 CL_Drop (); 192 recursive = false; 193 longjmp (abortframe, -1); 194 } 195 else if (code == ERR_DROP) 196 { 197 Com_Printf ("********************\nERROR: %s\n********************\n", msg); 198 SV_Shutdown (va("Server crashed: %s\n", msg), false); 199 CL_Drop (); 200 recursive = false; 201 longjmp (abortframe, -1); 202 } 203 else 204 { 205 SV_Shutdown (va("Server fatal crashed: %s\n", msg), false); 206 CL_Shutdown (); 207 } 208 209 if (logfile) 210 { 211 fclose (logfile); 212 logfile = NULL; 213 } 214 215 Sys_Error ("%s", msg); 216 } 217 218 219 /* 220 ============= 221 Com_Quit 222 223 Both client and server can use this, and it will 224 do the apropriate things. 225 ============= 226 */ 227 void Com_Quit (void) 228 { 229 SV_Shutdown ("Server quit\n", false); 230 CL_Shutdown (); 231 232 if (logfile) 233 { 234 fclose (logfile); 235 logfile = NULL; 236 } 237 238 Sys_Quit (); 239 } 240 241 242 /* 243 ================== 244 Com_ServerState 245 ================== 246 */ 247 int Com_ServerState (void) 248 { 249 return server_state; 250 } 251 252 /* 253 ================== 254 Com_SetServerState 255 ================== 256 */ 257 void Com_SetServerState (int state) 258 { 259 server_state = state; 260 } 261 262 263 /* 264 ============================================================================== 265 266 MESSAGE IO FUNCTIONS 267 268 Handles byte ordering and avoids alignment errors 269 ============================================================================== 270 */ 271 272 vec3_t bytedirs[NUMVERTEXNORMALS] = 273 { 274 #include "../client/anorms.h" 275 }; 276 277 // 278 // writing functions 279 // 280 281 void MSG_WriteChar (sizebuf_t *sb, int c) 282 { 283 byte *buf; 284 285 #ifdef PARANOID 286 if (c < -128 || c > 127) 287 Com_Error (ERR_FATAL, "MSG_WriteChar: range error"); 288 #endif 289 290 buf = SZ_GetSpace (sb, 1); 291 buf[0] = c; 292 } 293 294 void MSG_WriteByte (sizebuf_t *sb, int c) 295 { 296 byte *buf; 297 298 #ifdef PARANOID 299 if (c < 0 || c > 255) 300 Com_Error (ERR_FATAL, "MSG_WriteByte: range error"); 301 #endif 302 303 buf = SZ_GetSpace (sb, 1); 304 buf[0] = c; 305 } 306 307 void MSG_WriteShort (sizebuf_t *sb, int c) 308 { 309 byte *buf; 310 311 #ifdef PARANOID 312 if (c < ((short)0x8000) || c > (short)0x7fff) 313 Com_Error (ERR_FATAL, "MSG_WriteShort: range error"); 314 #endif 315 316 buf = SZ_GetSpace (sb, 2); 317 buf[0] = c&0xff; 318 buf[1] = c>>8; 319 } 320 321 void MSG_WriteLong (sizebuf_t *sb, int c) 322 { 323 byte *buf; 324 325 buf = SZ_GetSpace (sb, 4); 326 buf[0] = c&0xff; 327 buf[1] = (c>>8)&0xff; 328 buf[2] = (c>>16)&0xff; 329 buf[3] = c>>24; 330 } 331 332 void MSG_WriteFloat (sizebuf_t *sb, float f) 333 { 334 union 335 { 336 float f; 337 int l; 338 } dat; 339 340 341 dat.f = f; 342 dat.l = LittleLong (dat.l); 343 344 SZ_Write (sb, &dat.l, 4); 345 } 346 347 void MSG_WriteString (sizebuf_t *sb, char *s) 348 { 349 if (!s) 350 SZ_Write (sb, "", 1); 351 else 352 SZ_Write (sb, s, strlen(s)+1); 353 } 354 355 void MSG_WriteCoord (sizebuf_t *sb, float f) 356 { 357 MSG_WriteShort (sb, (int)(f*8)); 358 } 359 360 void MSG_WritePos (sizebuf_t *sb, vec3_t pos) 361 { 362 MSG_WriteShort (sb, (int)(pos[0]*8)); 363 MSG_WriteShort (sb, (int)(pos[1]*8)); 364 MSG_WriteShort (sb, (int)(pos[2]*8)); 365 } 366 367 void MSG_WriteAngle (sizebuf_t *sb, float f) 368 { 369 MSG_WriteByte (sb, (int)(f*256/360) & 255); 370 } 371 372 void MSG_WriteAngle16 (sizebuf_t *sb, float f) 373 { 374 MSG_WriteShort (sb, ANGLE2SHORT(f)); 375 } 376 377 378 void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) 379 { 380 int bits; 381 382 // 383 // send the movement message 384 // 385 bits = 0; 386 if (cmd->angles[0] != from->angles[0]) 387 bits |= CM_ANGLE1; 388 if (cmd->angles[1] != from->angles[1]) 389 bits |= CM_ANGLE2; 390 if (cmd->angles[2] != from->angles[2]) 391 bits |= CM_ANGLE3; 392 if (cmd->forwardmove != from->forwardmove) 393 bits |= CM_FORWARD; 394 if (cmd->sidemove != from->sidemove) 395 bits |= CM_SIDE; 396 if (cmd->upmove != from->upmove) 397 bits |= CM_UP; 398 if (cmd->buttons != from->buttons) 399 bits |= CM_BUTTONS; 400 if (cmd->impulse != from->impulse) 401 bits |= CM_IMPULSE; 402 403 MSG_WriteByte (buf, bits); 404 405 if (bits & CM_ANGLE1) 406 MSG_WriteShort (buf, cmd->angles[0]); 407 if (bits & CM_ANGLE2) 408 MSG_WriteShort (buf, cmd->angles[1]); 409 if (bits & CM_ANGLE3) 410 MSG_WriteShort (buf, cmd->angles[2]); 411 412 if (bits & CM_FORWARD) 413 MSG_WriteShort (buf, cmd->forwardmove); 414 if (bits & CM_SIDE) 415 MSG_WriteShort (buf, cmd->sidemove); 416 if (bits & CM_UP) 417 MSG_WriteShort (buf, cmd->upmove); 418 419 if (bits & CM_BUTTONS) 420 MSG_WriteByte (buf, cmd->buttons); 421 if (bits & CM_IMPULSE) 422 MSG_WriteByte (buf, cmd->impulse); 423 424 MSG_WriteByte (buf, cmd->msec); 425 MSG_WriteByte (buf, cmd->lightlevel); 426 } 427 428 429 void MSG_WriteDir (sizebuf_t *sb, vec3_t dir) 430 { 431 int i, best; 432 float d, bestd; 433 434 if (!dir) 435 { 436 MSG_WriteByte (sb, 0); 437 return; 438 } 439 440 bestd = 0; 441 best = 0; 442 for (i=0 ; i<NUMVERTEXNORMALS ; i++) 443 { 444 d = DotProduct (dir, bytedirs[i]); 445 if (d > bestd) 446 { 447 bestd = d; 448 best = i; 449 } 450 } 451 MSG_WriteByte (sb, best); 452 } 453 454 455 void MSG_ReadDir (sizebuf_t *sb, vec3_t dir) 456 { 457 int b; 458 459 b = MSG_ReadByte (sb); 460 if (b >= NUMVERTEXNORMALS) 461 Com_Error (ERR_DROP, "MSF_ReadDir: out of range"); 462 VectorCopy (bytedirs[b], dir); 463 } 464 465 466 /* 467 ================== 468 MSG_WriteDeltaEntity 469 470 Writes part of a packetentities message. 471 Can delta from either a baseline or a previous packet_entity 472 ================== 473 */ 474 void MSG_WriteDeltaEntity (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean newentity) 475 { 476 int bits; 477 478 if (!to->number) 479 Com_Error (ERR_FATAL, "Unset entity number"); 480 if (to->number >= MAX_EDICTS) 481 Com_Error (ERR_FATAL, "Entity number >= MAX_EDICTS"); 482 483 // send an update 484 bits = 0; 485 486 if (to->number >= 256) 487 bits |= U_NUMBER16; // number8 is implicit otherwise 488 489 if (to->origin[0] != from->origin[0]) 490 bits |= U_ORIGIN1; 491 if (to->origin[1] != from->origin[1]) 492 bits |= U_ORIGIN2; 493 if (to->origin[2] != from->origin[2]) 494 bits |= U_ORIGIN3; 495 496 if ( to->angles[0] != from->angles[0] ) 497 bits |= U_ANGLE1; 498 if ( to->angles[1] != from->angles[1] ) 499 bits |= U_ANGLE2; 500 if ( to->angles[2] != from->angles[2] ) 501 bits |= U_ANGLE3; 502 503 if ( to->skinnum != from->skinnum ) 504 { 505 if ((unsigned)to->skinnum < 256) 506 bits |= U_SKIN8; 507 else if ((unsigned)to->skinnum < 0x10000) 508 bits |= U_SKIN16; 509 else 510 bits |= (U_SKIN8|U_SKIN16); 511 } 512 513 if ( to->frame != from->frame ) 514 { 515 if (to->frame < 256) 516 bits |= U_FRAME8; 517 else 518 bits |= U_FRAME16; 519 } 520 521 if ( to->effects != from->effects ) 522 { 523 if (to->effects < 256) 524 bits |= U_EFFECTS8; 525 else if (to->effects < 0x8000) 526 bits |= U_EFFECTS16; 527 else 528 bits |= U_EFFECTS8|U_EFFECTS16; 529 } 530 531 if ( to->renderfx != from->renderfx ) 532 { 533 if (to->renderfx < 256) 534 bits |= U_RENDERFX8; 535 else if (to->renderfx < 0x8000) 536 bits |= U_RENDERFX16; 537 else 538 bits |= U_RENDERFX8|U_RENDERFX16; 539 } 540 541 if ( to->solid != from->solid ) 542 bits |= U_SOLID; 543 544 // event is not delta compressed, just 0 compressed 545 if ( to->event ) 546 bits |= U_EVENT; 547 548 if ( to->modelindex != from->modelindex ) 549 bits |= U_MODEL; 550 if ( to->modelindex2 != from->modelindex2 ) 551 bits |= U_MODEL2; 552 if ( to->modelindex3 != from->modelindex3 ) 553 bits |= U_MODEL3; 554 if ( to->modelindex4 != from->modelindex4 ) 555 bits |= U_MODEL4; 556 557 if ( to->sound != from->sound ) 558 bits |= U_SOUND; 559 560 if (newentity || (to->renderfx & RF_BEAM)) 561 bits |= U_OLDORIGIN; 562 563 // 564 // write the message 565 // 566 if (!bits && !force) 567 return; // nothing to send! 568 569 //---------- 570 571 if (bits & 0xff000000) 572 bits |= U_MOREBITS3 | U_MOREBITS2 | U_MOREBITS1; 573 else if (bits & 0x00ff0000) 574 bits |= U_MOREBITS2 | U_MOREBITS1; 575 else if (bits & 0x0000ff00) 576 bits |= U_MOREBITS1; 577 578 MSG_WriteByte (msg, bits&255 ); 579 580 if (bits & 0xff000000) 581 { 582 MSG_WriteByte (msg, (bits>>8)&255 ); 583 MSG_WriteByte (msg, (bits>>16)&255 ); 584 MSG_WriteByte (msg, (bits>>24)&255 ); 585 } 586 else if (bits & 0x00ff0000) 587 { 588 MSG_WriteByte (msg, (bits>>8)&255 ); 589 MSG_WriteByte (msg, (bits>>16)&255 ); 590 } 591 else if (bits & 0x0000ff00) 592 { 593 MSG_WriteByte (msg, (bits>>8)&255 ); 594 } 595 596 //---------- 597 598 if (bits & U_NUMBER16) 599 MSG_WriteShort (msg, to->number); 600 else 601 MSG_WriteByte (msg, to->number); 602 603 if (bits & U_MODEL) 604 MSG_WriteByte (msg, to->modelindex); 605 if (bits & U_MODEL2) 606 MSG_WriteByte (msg, to->modelindex2); 607 if (bits & U_MODEL3) 608 MSG_WriteByte (msg, to->modelindex3); 609 if (bits & U_MODEL4) 610 MSG_WriteByte (msg, to->modelindex4); 611 612 if (bits & U_FRAME8) 613 MSG_WriteByte (msg, to->frame); 614 if (bits & U_FRAME16) 615 MSG_WriteShort (msg, to->frame); 616 617 if ((bits & U_SKIN8) && (bits & U_SKIN16)) //used for laser colors 618 MSG_WriteLong (msg, to->skinnum); 619 else if (bits & U_SKIN8) 620 MSG_WriteByte (msg, to->skinnum); 621 else if (bits & U_SKIN16) 622 MSG_WriteShort (msg, to->skinnum); 623 624 625 if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) ) 626 MSG_WriteLong (msg, to->effects); 627 else if (bits & U_EFFECTS8) 628 MSG_WriteByte (msg, to->effects); 629 else if (bits & U_EFFECTS16) 630 MSG_WriteShort (msg, to->effects); 631 632 if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) ) 633 MSG_WriteLong (msg, to->renderfx); 634 else if (bits & U_RENDERFX8) 635 MSG_WriteByte (msg, to->renderfx); 636 else if (bits & U_RENDERFX16) 637 MSG_WriteShort (msg, to->renderfx); 638 639 if (bits & U_ORIGIN1) 640 MSG_WriteCoord (msg, to->origin[0]); 641 if (bits & U_ORIGIN2) 642 MSG_WriteCoord (msg, to->origin[1]); 643 if (bits & U_ORIGIN3) 644 MSG_WriteCoord (msg, to->origin[2]); 645 646 if (bits & U_ANGLE1) 647 MSG_WriteAngle(msg, to->angles[0]); 648 if (bits & U_ANGLE2) 649 MSG_WriteAngle(msg, to->angles[1]); 650 if (bits & U_ANGLE3) 651 MSG_WriteAngle(msg, to->angles[2]); 652 653 if (bits & U_OLDORIGIN) 654 { 655 MSG_WriteCoord (msg, to->old_origin[0]); 656 MSG_WriteCoord (msg, to->old_origin[1]); 657 MSG_WriteCoord (msg, to->old_origin[2]); 658 } 659 660 if (bits & U_SOUND) 661 MSG_WriteByte (msg, to->sound); 662 if (bits & U_EVENT) 663 MSG_WriteByte (msg, to->event); 664 if (bits & U_SOLID) 665 MSG_WriteShort (msg, to->solid); 666 } 667 668 669 //============================================================ 670 671 // 672 // reading functions 673 // 674 675 void MSG_BeginReading (sizebuf_t *msg) 676 { 677 msg->readcount = 0; 678 } 679 680 // returns -1 if no more characters are available 681 int MSG_ReadChar (sizebuf_t *msg_read) 682 { 683 int c; 684 685 if (msg_read->readcount+1 > msg_read->cursize) 686 c = -1; 687 else 688 c = (signed char)msg_read->data[msg_read->readcount]; 689 msg_read->readcount++; 690 691 return c; 692 } 693 694 int MSG_ReadByte (sizebuf_t *msg_read) 695 { 696 int c; 697 698 if (msg_read->readcount+1 > msg_read->cursize) 699 c = -1; 700 else 701 c = (unsigned char)msg_read->data[msg_read->readcount]; 702 msg_read->readcount++; 703 704 return c; 705 } 706 707 int MSG_ReadShort (sizebuf_t *msg_read) 708 { 709 int c; 710 711 if (msg_read->readcount+2 > msg_read->cursize) 712 c = -1; 713 else 714 c = (short)(msg_read->data[msg_read->readcount] 715 + (msg_read->data[msg_read->readcount+1]<<8)); 716 717 msg_read->readcount += 2; 718 719 return c; 720 } 721 722 int MSG_ReadLong (sizebuf_t *msg_read) 723 { 724 int c; 725 726 if (msg_read->readcount+4 > msg_read->cursize) 727 c = -1; 728 else 729 c = msg_read->data[msg_read->readcount] 730 + (msg_read->data[msg_read->readcount+1]<<8) 731 + (msg_read->data[msg_read->readcount+2]<<16) 732 + (msg_read->data[msg_read->readcount+3]<<24); 733 734 msg_read->readcount += 4; 735 736 return c; 737 } 738 739 float MSG_ReadFloat (sizebuf_t *msg_read) 740 { 741 union 742 { 743 byte b[4]; 744 float f; 745 int l; 746 } dat; 747 748 if (msg_read->readcount+4 > msg_read->cursize) 749 dat.f = -1; 750 else 751 { 752 dat.b[0] = msg_read->data[msg_read->readcount]; 753 dat.b[1] = msg_read->data[msg_read->readcount+1]; 754 dat.b[2] = msg_read->data[msg_read->readcount+2]; 755 dat.b[3] = msg_read->data[msg_read->readcount+3]; 756 } 757 msg_read->readcount += 4; 758 759 dat.l = LittleLong (dat.l); 760 761 return dat.f; 762 } 763 764 char *MSG_ReadString (sizebuf_t *msg_read) 765 { 766 static char string[2048]; 767 int l,c; 768 769 l = 0; 770 do 771 { 772 c = MSG_ReadChar (msg_read); 773 if (c == -1 || c == 0) 774 break; 775 string[l] = c; 776 l++; 777 } while (l < sizeof(string)-1); 778 779 string[l] = 0; 780 781 return string; 782 } 783 784 char *MSG_ReadStringLine (sizebuf_t *msg_read) 785 { 786 static char string[2048]; 787 int l,c; 788 789 l = 0; 790 do 791 { 792 c = MSG_ReadChar (msg_read); 793 if (c == -1 || c == 0 || c == '\n') 794 break; 795 string[l] = c; 796 l++; 797 } while (l < sizeof(string)-1); 798 799 string[l] = 0; 800 801 return string; 802 } 803 804 float MSG_ReadCoord (sizebuf_t *msg_read) 805 { 806 return MSG_ReadShort(msg_read) * (1.0/8); 807 } 808 809 void MSG_ReadPos (sizebuf_t *msg_read, vec3_t pos) 810 { 811 pos[0] = MSG_ReadShort(msg_read) * (1.0/8); 812 pos[1] = MSG_ReadShort(msg_read) * (1.0/8); 813 pos[2] = MSG_ReadShort(msg_read) * (1.0/8); 814 } 815 816 float MSG_ReadAngle (sizebuf_t *msg_read) 817 { 818 return MSG_ReadChar(msg_read) * (360.0/256); 819 } 820 821 float MSG_ReadAngle16 (sizebuf_t *msg_read) 822 { 823 return SHORT2ANGLE(MSG_ReadShort(msg_read)); 824 } 825 826 void MSG_ReadDeltaUsercmd (sizebuf_t *msg_read, usercmd_t *from, usercmd_t *move) 827 { 828 int bits; 829 830 memcpy (move, from, sizeof(*move)); 831 832 bits = MSG_ReadByte (msg_read); 833 834 // read current angles 835 if (bits & CM_ANGLE1) 836 move->angles[0] = MSG_ReadShort (msg_read); 837 if (bits & CM_ANGLE2) 838 move->angles[1] = MSG_ReadShort (msg_read); 839 if (bits & CM_ANGLE3) 840 move->angles[2] = MSG_ReadShort (msg_read); 841 842 // read movement 843 if (bits & CM_FORWARD) 844 move->forwardmove = MSG_ReadShort (msg_read); 845 if (bits & CM_SIDE) 846 move->sidemove = MSG_ReadShort (msg_read); 847 if (bits & CM_UP) 848 move->upmove = MSG_ReadShort (msg_read); 849 850 // read buttons 851 if (bits & CM_BUTTONS) 852 move->buttons = MSG_ReadByte (msg_read); 853 854 if (bits & CM_IMPULSE) 855 move->impulse = MSG_ReadByte (msg_read); 856 857 // read time to run command 858 move->msec = MSG_ReadByte (msg_read); 859 860 // read the light level 861 move->lightlevel = MSG_ReadByte (msg_read); 862 } 863 864 865 void MSG_ReadData (sizebuf_t *msg_read, void *data, int len) 866 { 867 int i; 868 869 for (i=0 ; i<len ; i++) 870 ((byte *)data)[i] = MSG_ReadByte (msg_read); 871 } 872 873 874 //=========================================================================== 875 876 void SZ_Init (sizebuf_t *buf, byte *data, int length) 877 { 878 memset (buf, 0, sizeof(*buf)); 879 buf->data = data; 880 buf->maxsize = length; 881 } 882 883 void SZ_Clear (sizebuf_t *buf) 884 { 885 buf->cursize = 0; 886 buf->overflowed = false; 887 } 888 889 void *SZ_GetSpace (sizebuf_t *buf, int length) 890 { 891 void *data; 892 893 if (buf->cursize + length > buf->maxsize) 894 { 895 if (!buf->allowoverflow) 896 Com_Error (ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set"); 897 898 if (length > buf->maxsize) 899 Com_Error (ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length); 900 901 Com_Printf ("SZ_GetSpace: overflow\n"); 902 SZ_Clear (buf); 903 buf->overflowed = true; 904 } 905 906 data = buf->data + buf->cursize; 907 buf->cursize += length; 908 909 return data; 910 } 911 912 void SZ_Write (sizebuf_t *buf, void *data, int length) 913 { 914 memcpy (SZ_GetSpace(buf,length),data,length); 915 } 916 917 void SZ_Print (sizebuf_t *buf, char *data) 918 { 919 int len; 920 921 len = strlen(data)+1; 922 923 if (buf->cursize) 924 { 925 if (buf->data[buf->cursize-1]) 926 memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 927 else 928 memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 929 } 930 else 931 memcpy ((byte *)SZ_GetSpace(buf, len),data,len); 932 } 933 934 935 //============================================================================ 936 937 938 /* 939 ================ 940 COM_CheckParm 941 942 Returns the position (1 to argc-1) in the program's argument list 943 where the given parameter apears, or 0 if not present 944 ================ 945 */ 946 int COM_CheckParm (char *parm) 947 { 948 int i; 949 950 for (i=1 ; i<com_argc ; i++) 951 { 952 if (!strcmp (parm,com_argv[i])) 953 return i; 954 } 955 956 return 0; 957 } 958 959 int COM_Argc (void) 960 { 961 return com_argc; 962 } 963 964 char *COM_Argv (int arg) 965 { 966 if (arg < 0 || arg >= com_argc || !com_argv[arg]) 967 return ""; 968 return com_argv[arg]; 969 } 970 971 void COM_ClearArgv (int arg) 972 { 973 if (arg < 0 || arg >= com_argc || !com_argv[arg]) 974 return; 975 com_argv[arg] = ""; 976 } 977 978 979 /* 980 ================ 981 COM_InitArgv 982 ================ 983 */ 984 void COM_InitArgv (int argc, char **argv) 985 { 986 int i; 987 988 if (argc > MAX_NUM_ARGVS) 989 Com_Error (ERR_FATAL, "argc > MAX_NUM_ARGVS"); 990 com_argc = argc; 991 for (i=0 ; i<argc ; i++) 992 { 993 if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS ) 994 com_argv[i] = ""; 995 else 996 com_argv[i] = argv[i]; 997 } 998 } 999 1000 /* 1001 ================ 1002 COM_AddParm 1003 1004 Adds the given string at the end of the current argument list 1005 ================ 1006 */ 1007 void COM_AddParm (char *parm) 1008 { 1009 if (com_argc == MAX_NUM_ARGVS) 1010 Com_Error (ERR_FATAL, "COM_AddParm: MAX_NUM)ARGS"); 1011 com_argv[com_argc++] = parm; 1012 } 1013 1014 1015 1016 1017 /// just for debugging 1018 int memsearch (byte *start, int count, int search) 1019 { 1020 int i; 1021 1022 for (i=0 ; i<count ; i++) 1023 if (start[i] == search) 1024 return i; 1025 return -1; 1026 } 1027 1028 1029 char *CopyString (char *in) 1030 { 1031 char *out; 1032 1033 out = Z_Malloc (strlen(in)+1); 1034 strcpy (out, in); 1035 return out; 1036 } 1037 1038 1039 1040 void Info_Print (char *s) 1041 { 1042 char key[512]; 1043 char value[512]; 1044 char *o; 1045 int l; 1046 1047 if (*s == '\\') 1048 s++; 1049 while (*s) 1050 { 1051 o = key; 1052 while (*s && *s != '\\') 1053 *o++ = *s++; 1054 1055 l = o - key; 1056 if (l < 20) 1057 { 1058 memset (o, ' ', 20-l); 1059 key[20] = 0; 1060 } 1061 else 1062 *o = 0; 1063 Com_Printf ("%s", key); 1064 1065 if (!*s) 1066 { 1067 Com_Printf ("MISSING VALUE\n"); 1068 return; 1069 } 1070 1071 o = value; 1072 s++; 1073 while (*s && *s != '\\') 1074 *o++ = *s++; 1075 *o = 0; 1076 1077 if (*s) 1078 s++; 1079 Com_Printf ("%s\n", value); 1080 } 1081 } 1082 1083 1084 /* 1085 ============================================================================== 1086 1087 ZONE MEMORY ALLOCATION 1088 1089 just cleared malloc with counters now... 1090 1091 ============================================================================== 1092 */ 1093 1094 #define Z_MAGIC 0x1d1d 1095 1096 1097 typedef struct zhead_s 1098 { 1099 struct zhead_s *prev, *next; 1100 short magic; 1101 short tag; // for group free 1102 int size; 1103 } zhead_t; 1104 1105 zhead_t z_chain; 1106 int z_count, z_bytes; 1107 1108 /* 1109 ======================== 1110 Z_Free 1111 ======================== 1112 */ 1113 void Z_Free (void *ptr) 1114 { 1115 zhead_t *z; 1116 1117 z = ((zhead_t *)ptr) - 1; 1118 1119 if (z->magic != Z_MAGIC) 1120 Com_Error (ERR_FATAL, "Z_Free: bad magic"); 1121 1122 z->prev->next = z->next; 1123 z->next->prev = z->prev; 1124 1125 z_count--; 1126 z_bytes -= z->size; 1127 free (z); 1128 } 1129 1130 1131 /* 1132 ======================== 1133 Z_Stats_f 1134 ======================== 1135 */ 1136 void Z_Stats_f (void) 1137 { 1138 Com_Printf ("%i bytes in %i blocks\n", z_bytes, z_count); 1139 } 1140 1141 /* 1142 ======================== 1143 Z_FreeTags 1144 ======================== 1145 */ 1146 void Z_FreeTags (int tag) 1147 { 1148 zhead_t *z, *next; 1149 1150 for (z=z_chain.next ; z != &z_chain ; z=next) 1151 { 1152 next = z->next; 1153 if (z->tag == tag) 1154 Z_Free ((void *)(z+1)); 1155 } 1156 } 1157 1158 /* 1159 ======================== 1160 Z_TagMalloc 1161 ======================== 1162 */ 1163 void *Z_TagMalloc (int size, int tag) 1164 { 1165 zhead_t *z; 1166 1167 size = size + sizeof(zhead_t); 1168 z = malloc(size); 1169 if (!z) 1170 Com_Error (ERR_FATAL, "Z_Malloc: failed on allocation of %i bytes",size); 1171 memset (z, 0, size); 1172 z_count++; 1173 z_bytes += size; 1174 z->magic = Z_MAGIC; 1175 z->tag = tag; 1176 z->size = size; 1177 1178 z->next = z_chain.next; 1179 z->prev = &z_chain; 1180 z_chain.next->prev = z; 1181 z_chain.next = z; 1182 1183 return (void *)(z+1); 1184 } 1185 1186 /* 1187 ======================== 1188 Z_Malloc 1189 ======================== 1190 */ 1191 void *Z_Malloc (int size) 1192 { 1193 return Z_TagMalloc (size, 0); 1194 } 1195 1196 1197 //============================================================================ 1198 1199 1200 /* 1201 ==================== 1202 COM_BlockSequenceCheckByte 1203 1204 For proxy protecting 1205 1206 // THIS IS MASSIVELY BROKEN! CHALLENGE MAY BE NEGATIVE 1207 // DON'T USE THIS FUNCTION!!!!! 1208 1209 ==================== 1210 */ 1211 byte COM_BlockSequenceCheckByte (byte *base, int length, int sequence, int challenge) 1212 { 1213 Sys_Error("COM_BlockSequenceCheckByte called\n"); 1214 1215 #if 0 1216 int checksum; 1217 byte buf[68]; 1218 byte *p; 1219 float temp; 1220 byte c; 1221 1222 temp = bytedirs[(sequence/3) % NUMVERTEXNORMALS][sequence % 3]; 1223 temp = LittleFloat(temp); 1224 p = ((byte *)&temp); 1225 1226 if (length > 60) 1227 length = 60; 1228 memcpy (buf, base, length); 1229 1230 buf[length] = (sequence & 0xff) ^ p[0]; 1231 buf[length+1] = p[1]; 1232 buf[length+2] = ((sequence>>8) & 0xff) ^ p[2]; 1233 buf[length+3] = p[3]; 1234 1235 temp = bytedirs[((sequence+challenge)/3) % NUMVERTEXNORMALS][(sequence+challenge) % 3]; 1236 temp = LittleFloat(temp); 1237 p = ((byte *)&temp); 1238 1239 buf[length+4] = (sequence & 0xff) ^ p[3]; 1240 buf[length+5] = (challenge & 0xff) ^ p[2]; 1241 buf[length+6] = ((sequence>>8) & 0xff) ^ p[1]; 1242 buf[length+7] = ((challenge >> 7) & 0xff) ^ p[0]; 1243 1244 length += 8; 1245 1246 checksum = LittleLong(Com_BlockChecksum (buf, length)); 1247 1248 checksum &= 0xff; 1249 1250 return checksum; 1251 #endif 1252 return 0; 1253 } 1254 1255 static byte chktbl[1024] = { 1256 0x84, 0x47, 0x51, 0xc1, 0x93, 0x22, 0x21, 0x24, 0x2f, 0x66, 0x60, 0x4d, 0xb0, 0x7c, 0xda, 1257 0x88, 0x54, 0x15, 0x2b, 0xc6, 0x6c, 0x89, 0xc5, 0x9d, 0x48, 0xee, 0xe6, 0x8a, 0xb5, 0xf4, 1258 0xcb, 0xfb, 0xf1, 0x0c, 0x2e, 0xa0, 0xd7, 0xc9, 0x1f, 0xd6, 0x06, 0x9a, 0x09, 0x41, 0x54, 1259 0x67, 0x46, 0xc7, 0x74, 0xe3, 0xc8, 0xb6, 0x5d, 0xa6, 0x36, 0xc4, 0xab, 0x2c, 0x7e, 0x85, 1260 0xa8, 0xa4, 0xa6, 0x4d, 0x96, 0x19, 0x19, 0x9a, 0xcc, 0xd8, 0xac, 0x39, 0x5e, 0x3c, 0xf2, 1261 0xf5, 0x5a, 0x72, 0xe5, 0xa9, 0xd1, 0xb3, 0x23, 0x82, 0x6f, 0x29, 0xcb, 0xd1, 0xcc, 0x71, 1262 0xfb, 0xea, 0x92, 0xeb, 0x1c, 0xca, 0x4c, 0x70, 0xfe, 0x4d, 0xc9, 0x67, 0x43, 0x47, 0x94, 1263 0xb9, 0x47, 0xbc, 0x3f, 0x01, 0xab, 0x7b, 0xa6, 0xe2, 0x76, 0xef, 0x5a, 0x7a, 0x29, 0x0b, 1264 0x51, 0x54, 0x67, 0xd8, 0x1c, 0x14, 0x3e, 0x29, 0xec, 0xe9, 0x2d, 0x48, 0x67, 0xff, 0xed, 1265 0x54, 0x4f, 0x48, 0xc0, 0xaa, 0x61, 0xf7, 0x78, 0x12, 0x03, 0x7a, 0x9e, 0x8b, 0xcf, 0x83, 1266 0x7b, 0xae, 0xca, 0x7b, 0xd9, 0xe9, 0x53, 0x2a, 0xeb, 0xd2, 0xd8, 0xcd, 0xa3, 0x10, 0x25, 1267 0x78, 0x5a, 0xb5, 0x23, 0x06, 0x93, 0xb7, 0x84, 0xd2, 0xbd, 0x96, 0x75, 0xa5, 0x5e, 0xcf, 1268 0x4e, 0xe9, 0x50, 0xa1, 0xe6, 0x9d, 0xb1, 0xe3, 0x85, 0x66, 0x28, 0x4e, 0x43, 0xdc, 0x6e, 1269 0xbb, 0x33, 0x9e, 0xf3, 0x0d, 0x00, 0xc1, 0xcf, 0x67, 0x34, 0x06, 0x7c, 0x71, 0xe3, 0x63, 1270 0xb7, 0xb7, 0xdf, 0x92, 0xc4, 0xc2, 0x25, 0x5c, 0xff, 0xc3, 0x6e, 0xfc, 0xaa, 0x1e, 0x2a, 1271 0x48, 0x11, 0x1c, 0x36, 0x68, 0x78, 0x86, 0x79, 0x30, 0xc3, 0xd6, 0xde, 0xbc, 0x3a, 0x2a, 1272 0x6d, 0x1e, 0x46, 0xdd, 0xe0, 0x80, 0x1e, 0x44, 0x3b, 0x6f, 0xaf, 0x31, 0xda, 0xa2, 0xbd, 1273 0x77, 0x06, 0x56, 0xc0, 0xb7, 0x92, 0x4b, 0x37, 0xc0, 0xfc, 0xc2, 0xd5, 0xfb, 0xa8, 0xda, 1274 0xf5, 0x57, 0xa8, 0x18, 0xc0, 0xdf, 0xe7, 0xaa, 0x2a, 0xe0, 0x7c, 0x6f, 0x77, 0xb1, 0x26, 1275 0xba, 0xf9, 0x2e, 0x1d, 0x16, 0xcb, 0xb8, 0xa2, 0x44, 0xd5, 0x2f, 0x1a, 0x79, 0x74, 0x87, 1276 0x4b, 0x00, 0xc9, 0x4a, 0x3a, 0x65, 0x8f, 0xe6, 0x5d, 0xe5, 0x0a, 0x77, 0xd8, 0x1a, 0x14, 1277 0x41, 0x75, 0xb1, 0xe2, 0x50, 0x2c, 0x93, 0x38, 0x2b, 0x6d, 0xf3, 0xf6, 0xdb, 0x1f, 0xcd, 1278 0xff, 0x14, 0x70, 0xe7, 0x16, 0xe8, 0x3d, 0xf0, 0xe3, 0xbc, 0x5e, 0xb6, 0x3f, 0xcc, 0x81, 1279 0x24, 0x67, 0xf3, 0x97, 0x3b, 0xfe, 0x3a, 0x96, 0x85, 0xdf, 0xe4, 0x6e, 0x3c, 0x85, 0x05, 1280 0x0e, 0xa3, 0x2b, 0x07, 0xc8, 0xbf, 0xe5, 0x13, 0x82, 0x62, 0x08, 0x61, 0x69, 0x4b, 0x47, 1281 0x62, 0x73, 0x44, 0x64, 0x8e, 0xe2, 0x91, 0xa6, 0x9a, 0xb7, 0xe9, 0x04, 0xb6, 0x54, 0x0c, 1282 0xc5, 0xa9, 0x47, 0xa6, 0xc9, 0x08, 0xfe, 0x4e, 0xa6, 0xcc, 0x8a, 0x5b, 0x90, 0x6f, 0x2b, 1283 0x3f, 0xb6, 0x0a, 0x96, 0xc0, 0x78, 0x58, 0x3c, 0x76, 0x6d, 0x94, 0x1a, 0xe4, 0x4e, 0xb8, 1284 0x38, 0xbb, 0xf5, 0xeb, 0x29, 0xd8, 0xb0, 0xf3, 0x15, 0x1e, 0x99, 0x96, 0x3c, 0x5d, 0x63, 1285 0xd5, 0xb1, 0xad, 0x52, 0xb8, 0x55, 0x70, 0x75, 0x3e, 0x1a, 0xd5, 0xda, 0xf6, 0x7a, 0x48, 1286 0x7d, 0x44, 0x41, 0xf9, 0x11, 0xce, 0xd7, 0xca, 0xa5, 0x3d, 0x7a, 0x79, 0x7e, 0x7d, 0x25, 1287 0x1b, 0x77, 0xbc, 0xf7, 0xc7, 0x0f, 0x84, 0x95, 0x10, 0x92, 0x67, 0x15, 0x11, 0x5a, 0x5e, 1288 0x41, 0x66, 0x0f, 0x38, 0x03, 0xb2, 0xf1, 0x5d, 0xf8, 0xab, 0xc0, 0x02, 0x76, 0x84, 0x28, 1289 0xf4, 0x9d, 0x56, 0x46, 0x60, 0x20, 0xdb, 0x68, 0xa7, 0xbb, 0xee, 0xac, 0x15, 0x01, 0x2f, 1290 0x20, 0x09, 0xdb, 0xc0, 0x16, 0xa1, 0x89, 0xf9, 0x94, 0x59, 0x00, 0xc1, 0x76, 0xbf, 0xc1, 1291 0x4d, 0x5d, 0x2d, 0xa9, 0x85, 0x2c, 0xd6, 0xd3, 0x14, 0xcc, 0x02, 0xc3, 0xc2, 0xfa, 0x6b, 1292 0xb7, 0xa6, 0xef, 0xdd, 0x12, 0x26, 0xa4, 0x63, 0xe3, 0x62, 0xbd, 0x56, 0x8a, 0x52, 0x2b, 1293 0xb9, 0xdf, 0x09, 0xbc, 0x0e, 0x97, 0xa9, 0xb0, 0x82, 0x46, 0x08, 0xd5, 0x1a, 0x8e, 0x1b, 1294 0xa7, 0x90, 0x98, 0xb9, 0xbb, 0x3c, 0x17, 0x9a, 0xf2, 0x82, 0xba, 0x64, 0x0a, 0x7f, 0xca, 1295 0x5a, 0x8c, 0x7c, 0xd3, 0x79, 0x09, 0x5b, 0x26, 0xbb, 0xbd, 0x25, 0xdf, 0x3d, 0x6f, 0x9a, 1296 0x8f, 0xee, 0x21, 0x66, 0xb0, 0x8d, 0x84, 0x4c, 0x91, 0x45, 0xd4, 0x77, 0x4f, 0xb3, 0x8c, 1297 0xbc, 0xa8, 0x99, 0xaa, 0x19, 0x53, 0x7c, 0x02, 0x87, 0xbb, 0x0b, 0x7c, 0x1a, 0x2d, 0xdf, 1298 0x48, 0x44, 0x06, 0xd6, 0x7d, 0x0c, 0x2d, 0x35, 0x76, 0xae, 0xc4, 0x5f, 0x71, 0x85, 0x97, 1299 0xc4, 0x3d, 0xef, 0x52, 0xbe, 0x00, 0xe4, 0xcd, 0x49, 0xd1, 0xd1, 0x1c, 0x3c, 0xd0, 0x1c, 1300 0x42, 0xaf, 0xd4, 0xbd, 0x58, 0x34, 0x07, 0x32, 0xee, 0xb9, 0xb5, 0xea, 0xff, 0xd7, 0x8c, 1301 0x0d, 0x2e, 0x2f, 0xaf, 0x87, 0xbb, 0xe6, 0x52, 0x71, 0x22, 0xf5, 0x25, 0x17, 0xa1, 0x82, 1302 0x04, 0xc2, 0x4a, 0xbd, 0x57, 0xc6, 0xab, 0xc8, 0x35, 0x0c, 0x3c, 0xd9, 0xc2, 0x43, 0xdb, 1303 0x27, 0x92, 0xcf, 0xb8, 0x25, 0x60, 0xfa, 0x21, 0x3b, 0x04, 0x52, 0xc8, 0x96, 0xba, 0x74, 1304 0xe3, 0x67, 0x3e, 0x8e, 0x8d, 0x61, 0x90, 0x92, 0x59, 0xb6, 0x1a, 0x1c, 0x5e, 0x21, 0xc1, 1305 0x65, 0xe5, 0xa6, 0x34, 0x05, 0x6f, 0xc5, 0x60, 0xb1, 0x83, 0xc1, 0xd5, 0xd5, 0xed, 0xd9, 1306 0xc7, 0x11, 0x7b, 0x49, 0x7a, 0xf9, 0xf9, 0x84, 0x47, 0x9b, 0xe2, 0xa5, 0x82, 0xe0, 0xc2, 1307 0x88, 0xd0, 0xb2, 0x58, 0x88, 0x7f, 0x45, 0x09, 0x67, 0x74, 0x61, 0xbf, 0xe6, 0x40, 0xe2, 1308 0x9d, 0xc2, 0x47, 0x05, 0x89, 0xed, 0xcb, 0xbb, 0xb7, 0x27, 0xe7, 0xdc, 0x7a, 0xfd, 0xbf, 1309 0xa8, 0xd0, 0xaa, 0x10, 0x39, 0x3c, 0x20, 0xf0, 0xd3, 0x6e, 0xb1, 0x72, 0xf8, 0xe6, 0x0f, 1310 0xef, 0x37, 0xe5, 0x09, 0x33, 0x5a, 0x83, 0x43, 0x80, 0x4f, 0x65, 0x2f, 0x7c, 0x8c, 0x6a, 1311 0xa0, 0x82, 0x0c, 0xd4, 0xd4, 0xfa, 0x81, 0x60, 0x3d, 0xdf, 0x06, 0xf1, 0x5f, 0x08, 0x0d, 1312 0x6d, 0x43, 0xf2, 0xe3, 0x11, 0x7d, 0x80, 0x32, 0xc5, 0xfb, 0xc5, 0xd9, 0x27, 0xec, 0xc6, 1313 0x4e, 0x65, 0x27, 0x76, 0x87, 0xa6, 0xee, 0xee, 0xd7, 0x8b, 0xd1, 0xa0, 0x5c, 0xb0, 0x42, 1314 0x13, 0x0e, 0x95, 0x4a, 0xf2, 0x06, 0xc6, 0x43, 0x33, 0xf4, 0xc7, 0xf8, 0xe7, 0x1f, 0xdd, 1315 0xe4, 0x46, 0x4a, 0x70, 0x39, 0x6c, 0xd0, 0xed, 0xca, 0xbe, 0x60, 0x3b, 0xd1, 0x7b, 0x57, 1316 0x48, 0xe5, 0x3a, 0x79, 0xc1, 0x69, 0x33, 0x53, 0x1b, 0x80, 0xb8, 0x91, 0x7d, 0xb4, 0xf6, 1317 0x17, 0x1a, 0x1d, 0x5a, 0x32, 0xd6, 0xcc, 0x71, 0x29, 0x3f, 0x28, 0xbb, 0xf3, 0x5e, 0x71, 1318 0xb8, 0x43, 0xaf, 0xf8, 0xb9, 0x64, 0xef, 0xc4, 0xa5, 0x6c, 0x08, 0x53, 0xc7, 0x00, 0x10, 1319 0x39, 0x4f, 0xdd, 0xe4, 0xb6, 0x19, 0x27, 0xfb, 0xb8, 0xf5, 0x32, 0x73, 0xe5, 0xcb, 0x32 1320 }; 1321 1322 /* 1323 ==================== 1324 COM_BlockSequenceCRCByte 1325 1326 For proxy protecting 1327 ==================== 1328 */ 1329 byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence) 1330 { 1331 int n; 1332 byte *p; 1333 int x; 1334 byte chkb[60 + 4]; 1335 unsigned short crc; 1336 1337 1338 if (sequence < 0) 1339 Sys_Error("sequence < 0, this shouldn't happen\n"); 1340 1341 p = chktbl + (sequence % (sizeof(chktbl) - 4)); 1342 1343 if (length > 60) 1344 length = 60; 1345 memcpy (chkb, base, length); 1346 1347 chkb[length] = p[0]; 1348 chkb[length+1] = p[1]; 1349 chkb[length+2] = p[2]; 1350 chkb[length+3] = p[3]; 1351 1352 length += 4; 1353 1354 crc = CRC_Block(chkb, length); 1355 1356 for (x=0, n=0; n<length; n++) 1357 x += chkb[n]; 1358 1359 crc = (crc ^ x) & 0xff; 1360 1361 return crc; 1362 } 1363 1364 //======================================================== 1365 1366 float frand(void) 1367 { 1368 return (rand()&32767)* (1.0/32767); 1369 } 1370 1371 float crand(void) 1372 { 1373 return (rand()&32767)* (2.0/32767) - 1; 1374 } 1375 1376 void Key_Init (void); 1377 void SCR_EndLoadingPlaque (void); 1378 1379 /* 1380 ============= 1381 Com_Error_f 1382 1383 Just throw a fatal error to 1384 test error shutdown procedures 1385 ============= 1386 */ 1387 void Com_Error_f (void) 1388 { 1389 Com_Error (ERR_FATAL, "%s", Cmd_Argv(1)); 1390 } 1391 1392 1393 /* 1394 ================= 1395 Qcommon_Init 1396 ================= 1397 */ 1398 void Qcommon_Init (int argc, char **argv) 1399 { 1400 char *s; 1401 1402 if (setjmp (abortframe) ) 1403 Sys_Error ("Error during initialization"); 1404 1405 z_chain.next = z_chain.prev = &z_chain; 1406 1407 // prepare enough of the subsystems to handle 1408 // cvar and command buffer management 1409 COM_InitArgv (argc, argv); 1410 1411 Swap_Init (); 1412 Cbuf_Init (); 1413 1414 Cmd_Init (); 1415 Cvar_Init (); 1416 1417 Key_Init (); 1418 1419 // we need to add the early commands twice, because 1420 // a basedir or cddir needs to be set before execing 1421 // config files, but we want other parms to override 1422 // the settings of the config files 1423 Cbuf_AddEarlyCommands (false); 1424 Cbuf_Execute (); 1425 1426 FS_InitFilesystem (); 1427 1428 Cbuf_AddText ("exec default.cfg\n"); 1429 Cbuf_AddText ("exec config.cfg\n"); 1430 1431 Cbuf_AddEarlyCommands (true); 1432 Cbuf_Execute (); 1433 1434 // 1435 // init commands and vars 1436 // 1437 Cmd_AddCommand ("z_stats", Z_Stats_f); 1438 Cmd_AddCommand ("error", Com_Error_f); 1439 1440 host_speeds = Cvar_Get ("host_speeds", "0", 0); 1441 log_stats = Cvar_Get ("log_stats", "0", 0); 1442 developer = Cvar_Get ("developer", "0", 0); 1443 timescale = Cvar_Get ("timescale", "1", 0); 1444 fixedtime = Cvar_Get ("fixedtime", "0", 0); 1445 logfile_active = Cvar_Get ("logfile", "0", 0); 1446 showtrace = Cvar_Get ("showtrace", "0", 0); 1447 #ifdef DEDICATED_ONLY 1448 dedicated = Cvar_Get ("dedicated", "1", CVAR_NOSET); 1449 #else 1450 dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET); 1451 #endif 1452 1453 s = va("%4.2f %s %s %s", VERSION, CPUSTRING, __DATE__, BUILDSTRING); 1454 Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET); 1455 1456 1457 if (dedicated->value) 1458 Cmd_AddCommand ("quit", Com_Quit); 1459 1460 Sys_Init (); 1461 1462 NET_Init (); 1463 Netchan_Init (); 1464 1465 SV_Init (); 1466 CL_Init (); 1467 1468 // add + commands from command line 1469 if (!Cbuf_AddLateCommands ()) 1470 { // if the user didn't give any commands, run default action 1471 if (!dedicated->value) 1472 Cbuf_AddText ("d1\n"); 1473 else 1474 Cbuf_AddText ("dedicated_start\n"); 1475 Cbuf_Execute (); 1476 } 1477 else 1478 { // the user asked for something explicit 1479 // so drop the loading plaque 1480 SCR_EndLoadingPlaque (); 1481 } 1482 1483 Com_Printf ("====== Quake2 Initialized ======\n\n"); 1484 } 1485 1486 /* 1487 ================= 1488 Qcommon_Frame 1489 ================= 1490 */ 1491 void Qcommon_Frame (int msec) 1492 { 1493 char *s; 1494 int time_before, time_between, time_after; 1495 1496 if (setjmp (abortframe) ) 1497 return; // an ERR_DROP was thrown 1498 1499 if ( log_stats->modified ) 1500 { 1501 log_stats->modified = false; 1502 if ( log_stats->value ) 1503 { 1504 if ( log_stats_file ) 1505 { 1506 fclose( log_stats_file ); 1507 log_stats_file = 0; 1508 } 1509 log_stats_file = fopen( "stats.log", "w" ); 1510 if ( log_stats_file ) 1511 fprintf( log_stats_file, "entities,dlights,parts,frame time\n" ); 1512 } 1513 else 1514 { 1515 if ( log_stats_file ) 1516 { 1517 fclose( log_stats_file ); 1518 log_stats_file = 0; 1519 } 1520 } 1521 } 1522 1523 if (fixedtime->value) 1524 msec = fixedtime->value; 1525 else if (timescale->value) 1526 { 1527 msec *= timescale->value; 1528 if (msec < 1) 1529 msec = 1; 1530 } 1531 1532 if (showtrace->value) 1533 { 1534 extern int c_traces, c_brush_traces; 1535 extern int c_pointcontents; 1536 1537 Com_Printf ("%4i traces %4i points\n", c_traces, c_pointcontents); 1538 c_traces = 0; 1539 c_brush_traces = 0; 1540 c_pointcontents = 0; 1541 } 1542 1543 do 1544 { 1545 s = Sys_ConsoleInput (); 1546 if (s) 1547 Cbuf_AddText (va("%s\n",s)); 1548 } while (s); 1549 Cbuf_Execute (); 1550 1551 if (host_speeds->value) 1552 time_before = Sys_Milliseconds (); 1553 1554 SV_Frame (msec); 1555 1556 if (host_speeds->value) 1557 time_between = Sys_Milliseconds (); 1558 1559 CL_Frame (msec); 1560 1561 if (host_speeds->value) 1562 time_after = Sys_Milliseconds (); 1563 1564 1565 if (host_speeds->value) 1566 { 1567 int all, sv, gm, cl, rf; 1568 1569 all = time_after - time_before; 1570 sv = time_between - time_before; 1571 cl = time_after - time_between; 1572 gm = time_after_game - time_before_game; 1573 rf = time_after_ref - time_before_ref; 1574 sv -= gm; 1575 cl -= rf; 1576 Com_Printf ("all:%3i sv:%3i gm:%3i cl:%3i rf:%3i\n", 1577 all, sv, gm, cl, rf); 1578 } 1579 } 1580 1581 /* 1582 ================= 1583 Qcommon_Shutdown 1584 ================= 1585 */ 1586 void Qcommon_Shutdown (void) 1587 { 1588 }