File: qcommon\common.c

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