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