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