|
|
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.