UFO: Alien Invasion
Loading...
Searching...
No Matches
common.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 1997-2001 Id Software, Inc.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "../shared/autoptr.h"
27#include "common.h"
28#include "http.h"
29#include "../server/server.h"
30#include "../shared/parse.h"
31#include "../ports/system.h"
32#include <set>
33#include <vector>
34#include <SDL.h>
35
36#define MAXPRINTMSG 4096
37#define MAX_NUM_ARGVS 50
38
40
41static int com_argc;
42static const char* com_argv[MAX_NUM_ARGVS + 1];
43
45
49static const char* consoleLogName = "ufoconsole.log";
50static cvar_t* logfile_active; /* 1 = buffer log, 2 = flush after each print */
52#ifndef DEDICATED_ONLY
55#endif
63
66
74
75#define TIMER_CHECK_INTERVAL 100
76#define TIMER_CHECK_LAG 3
77#define TIMER_LATENESS_HIGH 200
78#define TIMER_LATENESS_LOW 50
79#define TIMER_LATENESS_HISTORY 32
80
94
96public:
97 bool operator()(const ScheduleEventPtr& e1, const ScheduleEventPtr& e2) const {
98 return e1->when < e2->when;
99 }
100};
101
102typedef std::multiset<ScheduleEventPtr, CompareScheduleEvent> EventPriorityQueue;
104
105static void Schedule_Timer(cvar_t* freq, event_func* func, event_check_func* check, void* data);
106
110static const char *libNameSuffix[] = {
111 UFO_VERSION "." CPUSTRING "." SO_EXT,
112 UFO_VERSION "." SO_EXT,
113 CPUSTRING "." SO_EXT,
114 SO_EXT,
115 nullptr
116};
117
126void* Com_LoadLibrary (const char* path, const char* prefix)
127{
128 char fullPath[MAX_OSPATH];
129 void *library = nullptr;
130
131 for (int i = 0; libNameSuffix[i] != nullptr; i++) {
132 Com_sprintf(fullPath, sizeof(fullPath), "%s/%s.%s", path, prefix, libNameSuffix[i]);
133 Com_DPrintf(DEBUG_SYSTEM, "Attempting to load library: %s\n", fullPath);
134 library = SDL_LoadObject(fullPath);
135 if (library) {
136 break;
137 }
138 }
139
140 if (library) {
141 Com_Printf("Library '%s' loaded from %s\n", prefix, fullPath);
142 return library;
143 } else {
144 Com_Printf("Library '%s' could not be loaded from %s\n", prefix, path);
145 Com_DPrintf(DEBUG_SYSTEM, "%s\n", SDL_GetError());
146 return nullptr;
147 }
148}
149
150/*
151==============================================================================
152TARGETING FUNCTIONS
153==============================================================================
154*/
155
273float Com_GrenadeTarget (const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0)
274{
275 vec3_t delta;
276
277 /* calculate target distance and height */
278 const float h = at[2] - from[2];
279 VectorSubtract(at, from, delta);
280 delta[2] = 0;
281 const float d = VectorLength(delta);
282
283 /* check that it's not degenerate */
284 if (d == 0) {
285 return 0;
286 }
287
288 /* precalculate some useful values */
289 const float g = GRAVITY;
290 const float gd2 = g * d * d;
291 const float len = sqrt(h * h + d * d);
292
293 float v, alpha;
294 /* are we rolling? */
295 if (rolled) {
296 const float rollAngle = 3.0; /* angle to throw at for rolling, in degrees. */
297 alpha = rollAngle * torad;
298 const float theta = atan2(d, -h) - 2 * alpha;
299 const float k = gd2 / (len * cos(theta) - h);
300 if (k <= 0) /* impossible shot at any velocity */
301 return 0;
302 v = sqrt(k);
303 } else {
304 /* firstly try with the maximum speed possible */
305 v = speed;
306 const float k = (v * v * h + gd2) / (v * v * len);
307
308 /* check whether the shot's possible */
309 if (launched && k >= -1 && k <= 1) {
310 /* it is possible, so calculate the angle */
311 alpha = 0.5 * (atan2(d, -h) - acos(k));
312 } else {
313 /* calculate the minimum possible velocity that would make it possible */
314 alpha = 0.5 * atan2(d, -h);
315 v = sqrt(gd2 / (len - h));
316 }
317 }
318
319 /* calculate velocities */
320 const float vx = v * cos(alpha);
321 const float vy = v * sin(alpha);
322 VectorNormalizeFast(delta);
323 VectorScale(delta, vx, v0);
324 v0[2] = vy;
325
326 /* prevent any rounding errors */
328 VectorScale(v0, v - DIST_EPSILON, v0);
329
330 /* return time */
331 return d / vx;
332}
333
334/*
335============================================================================
336CLIENT / SERVER interactions
337============================================================================
338*/
339
340static char* rd_buffer;
341static unsigned int rd_buffersize;
342static struct net_stream* rd_stream;
343
350void Com_BeginRedirect (struct net_stream* stream, char* buffer, int buffersize)
351{
352 if (!buffer || !buffersize)
353 return;
354
356 rd_buffer = buffer;
357 if (buffersize > MAXPRINTMSG)
358 Com_Error(ERR_DROP, "redirect buffer may not be bigger than MAXPRINTMSG (%i)", MAXPRINTMSG);
359 rd_buffersize = buffersize;
360 rd_buffer[0] = '\0';
361}
362
368{
370
371 rd_stream = nullptr;
372 rd_buffer = nullptr;
373 rd_buffersize = 0;
374}
375
380void Com_vPrintf (const char* fmt, va_list ap)
381{
382 char msg[MAXPRINTMSG];
383
384 Q_vsnprintf(msg, sizeof(msg), fmt, ap);
385
386 /* redirect the output? */
387 if (rd_buffer) {
388 if ((strlen(msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) {
390 rd_buffer[0] = '\0';
391 }
392 Q_strcat(rd_buffer, sizeof(char) * rd_buffersize, "%s", msg);
393 return;
394 }
395
396 Con_Print(msg);
397
398 /* also echo to debugging console */
400
401 /* logfile */
402 if (logfile_active && logfile_active->integer) {
403 if (!logfile.f) {
404 if (logfile_active->integer > 2)
406 else
408 }
409 if (logfile.f) {
410 /* strip color codes */
411 const char* output = msg;
412
413 if (output[strlen(output) - 1] == '\n') {
414 char timestamp[40];
415 Com_MakeTimestamp(timestamp, sizeof(timestamp));
416 FS_Write(timestamp, strlen(timestamp), &logfile);
417 FS_Write(" ", 1, &logfile);
418 }
419
420 FS_Write(output, strlen(output), &logfile);
421
422 if (logfile_active->integer > 1)
423 fflush(logfile.f); /* force it to save every time */
424 }
425 }
426}
427
428void Com_Printf (const char* const fmt, ...)
429{
430 va_list ap;
431
432 va_start(ap, fmt);
433 vPrintfPtr(fmt, ap);
434 va_end(ap);
435}
436
440void Com_DPrintf (int level, const char* fmt, ...)
441{
442 /* don't confuse non-developers with techie stuff... */
443 if (!developer)
444 return;
445
446 if (developer->integer == 1 || (developer->integer & level)) {
447 va_list ap;
448
449 va_start(ap, fmt);
450 vPrintfPtr(fmt, ap);
451 va_end(ap);
452 }
453}
454
459void Com_Error (int code, const char* fmt, ...)
460{
461 va_list argptr;
462 static char msg[MAXPRINTMSG];
463 static bool recursive = false;
464
465 if (recursive)
466 Sys_Error("recursive error after: %s", msg);
467 recursive = true;
468
469 va_start(argptr, fmt);
470 Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
471 va_end(argptr);
472
473 switch (code) {
474 case ERR_DISCONNECT:
475 Com_Printf("%s\n", msg);
476 CL_Drop();
477 recursive = false;
478 Com_Drop();
479 case ERR_DROP:
480 Com_Printf("********************\n");
481 Com_Printf("ERROR: %s\n", msg);
482 Com_Printf("********************\n");
484 SV_Shutdown("Server crashed.", false);
485 CL_Drop();
486 recursive = false;
487 Com_Drop();
488 default:
489 Com_Printf("%s\n", msg);
490 SV_Shutdown("Server fatal crashed", false);
491
492 /* send an receive net messages a last time */
493 NET_Wait(0);
494
496 if (pipefile.f != nullptr) {
498 FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name));
499 }
500
501 CL_Shutdown();
503 Sys_Error("Shutdown");
504 }
505}
506
507void Com_Drop (void)
508{
509 throw comDrop_t();
510}
511
513{
514#ifdef DEBUG
515 SDL_MessageBoxData data;
516 SDL_MessageBoxButtonData okButton;
517 SDL_MessageBoxButtonData cancelButton;
518
519 OBJZERO(data);
520 OBJZERO(okButton);
521 OBJZERO(cancelButton);
522
523 okButton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
524 okButton.text = "Yes";
525 okButton.buttonid = 1;
526
527 cancelButton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
528 cancelButton.text = "No";
529 cancelButton.buttonid = 2;
530
531 const SDL_MessageBoxButtonData buttons[] = {okButton, cancelButton};
532 data.flags = SDL_MESSAGEBOX_ERROR;
533 data.title = "Error";
534 data.message = "Break into the debugger?";
535 data.numbuttons = lengthof(buttons);
536 data.buttons = buttons;
537 data.window = nullptr;
538
539 int buttonid = -1;
540 SDL_ShowMessageBox(&data, &buttonid);
541 if (buttonid == 1) {
543 }
544#endif
545}
546
551void Com_Quit (void)
552{
553#ifdef DEDICATED_ONLY
554 Com_WriteConfigToFile("dedconfig.cfg");
555#else
556 Com_WriteConfigToFile("config.cfg");
557#endif
558
559 SV_Shutdown("Server quit.", false);
560 SV_Clear();
561 CL_Shutdown();
562
563 /* send an receive net messages a last time */
564 NET_Wait(0);
566 if (pipefile.f != nullptr) {
568 FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name));
569 }
570 Sys_Quit();
571}
572
573
579{
580 return SV_GetServerState();
581}
582
587void Com_SetServerState (int state)
588{
589 Com_DPrintf(DEBUG_ENGINE, "Set server state to %i\n", state);
590 if (state == ss_dead)
591 SV_Shutdown("Server shutdown", false);
592 else if (state == ss_restart)
593 SV_Shutdown("Server map change", true);
594 sv->state = (server_state_t)state;
595}
596
600int Com_Argc (void)
601{
602 return com_argc;
603}
604
608const char* Com_Argv (int arg)
609{
610 if (arg < 0 || arg >= com_argc || !com_argv[arg])
611 return "";
612 return com_argv[arg];
613}
614
620void Com_ClearArgv (int arg)
621{
622 if (arg < 0 || arg >= com_argc || !com_argv[arg])
623 return;
624 com_argv[arg] = "";
625}
626
627static void Com_InitArgv (int argc, char** argv)
628{
629 if (argc > MAX_NUM_ARGVS)
630 Com_Error(ERR_FATAL, "argc > MAX_NUM_ARGVS");
631 com_argc = argc;
632 for (int i = 0; i < argc; i++) {
633 if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS)
634 com_argv[i] = "";
635 else
636 com_argv[i] = argv[i];
637 }
638}
639
640#define MACRO_CVAR_ID_LENGTH 6
647const char* Com_MacroExpandString (const char* text)
648{
649 static char expanded[MAX_STRING_CHARS];
650
651 const char* scan = text;
652 if (!text || !*text)
653 return nullptr;
654
655 const int len = strlen(scan);
656 if (len >= MAX_STRING_CHARS) {
657 Com_Printf("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
658 return nullptr;
659 }
660
661 bool inquote = false;
662 int count = 0;
663 OBJZERO(expanded);
664 char* pos = expanded;
665
666 /* also the \0 */
667 assert(scan[len] == '\0');
668 for (int i = 0; i <= len; i++) {
669 if (scan[i] == '"')
670 inquote ^= 1;
671 /* don't expand inside quotes */
672 if (inquote || strncmp(&scan[i], "*cvar:", MACRO_CVAR_ID_LENGTH)) {
673 *pos++ = scan[i];
674 continue;
675 }
676
677 /* scan out the complete macro and only parse the cvar name */
678 const char* start = &scan[i + MACRO_CVAR_ID_LENGTH];
679 const char* token = Com_Parse(&start);
680 if (!start)
681 continue;
682
683 /* skip the macro and the cvar name in the next loop */
685 i += strlen(token);
686 i--;
687
688 /* get the cvar value */
689 const char* cvarvalue = Cvar_GetString(token);
690 if (!cvarvalue) {
691 Com_Printf("Could not get cvar value for cvar: %s\n", token);
692 return nullptr;
693 }
694
695 const int j = strlen(cvarvalue);
696 if (strlen(pos) + j >= MAX_STRING_CHARS) {
697 Com_Printf("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
698 return nullptr;
699 }
700
701 /* copy the cvar value into the target buffer */
702 /* check for overflow is already done - so MAX_STRING_CHARS won't hurt here */
703 Q_strncpyz(pos, cvarvalue, j + 1);
704 pos += j;
705
706 if (++count == 100) {
707 Com_Printf("Macro expansion loop, discarded.\n");
708 return nullptr;
709 }
710 }
711
712 if (inquote) {
713 Com_Printf("Line has unmatched quote, discarded.\n");
714 return nullptr;
715 }
716
717 if (count)
718 return expanded;
719
720 return nullptr;
721}
722
734bool Com_ConsoleCompleteCommand (const char* s, char* target, size_t bufSize, uint32_t* pos, uint32_t offset)
735{
736 const char* cmd = nullptr, *cvar = nullptr, *use = nullptr;
737 char cmdLine[MAXCMDLINE] = "";
738 char cmdBase[MAXCMDLINE] = "";
739 bool append = true;
740
741 if (!s[0] || s[0] == ' ')
742 return false;
743
744 if (s[0] == '\\' || s[0] == '/') {
745 /* maybe we are using the same buffers - and we want to keep the slashes */
746 if (s == target)
747 offset++;
748 s++;
749 }
750
751 assert(bufSize <= MAXCMDLINE);
752 assert(pos);
753
754 /* don't try to search a command or cvar if we are already in the
755 * parameter stage */
756 if (strstr(s, " ")) {
757 Q_strncpyz(cmdLine, s, sizeof(cmdLine));
758 /* remove the last whitespace */
759 cmdLine[strlen(cmdLine) - 1] = '\0';
760
761 char* tmp = cmdBase;
762 while (*s != ' ')
763 *tmp++ = *s++;
764 /* get rid of the whitespace */
765 s++;
766 /* terminate the string at whitespace position to separate the cmd */
767 *tmp = '\0';
768
769 /* now strip away that part that is not yet completed */
770 tmp = strrchr(cmdLine, ' ');
771 if (tmp)
772 *tmp = '\0';
773
774 const int cntParams = Cmd_CompleteCommandParameters(cmdBase, s, &cmd);
775 if (cntParams > 1)
776 Com_Printf("\n");
777 if (cmd) {
778 /* append the found parameter */
779 Q_strcat(cmdLine, sizeof(cmdLine), " %s", cmd);
780 append = false;
781 use = cmdLine;
782 } else
783 return false;
784 } else {
785 /* Cmd_GenericCompleteFunction uses one static buffer for output, so backup one completion here if available */
786 static char cmdBackup[MAX_QPATH];
787 const int cntCmd = Cmd_CompleteCommand(s, &cmd);
788 if (cmd)
789 Q_strncpyz(cmdBackup, cmd, sizeof(cmdBackup));
790 const int cntCvar = Cvar_CompleteVariable(s, &cvar);
791
792 /* complete as much as possible, append only if one single match is found */
793 if (cntCmd > 0 && !cntCvar) {
794 use = cmd;
795 if (cntCmd != 1)
796 append = false;
797 } else if (!cntCmd && cntCvar > 0) {
798 use = cvar;
799 if (cntCvar != 1)
800 append = false;
801 } else if (cmd && cvar) {
802 const int maxLength = std::min(strlen(cmdBackup),strlen(cvar));
803 int idx = 0;
804 /* try to find similar content of cvar and cmd match */
805 Q_strncpyz(cmdLine, cmdBackup,sizeof(cmdLine));
806 for (; idx < maxLength; idx++) {
807 if (cmdBackup[idx] != cvar[idx]) {
808 cmdLine[idx] = '\0';
809 break;
810 }
811 }
812 if (idx == maxLength)
813 cmdLine[idx] = '\0';
814 use = cmdLine;
815 append = false;
816 }
817 }
818
819 if (use) {
820 Q_strncpyz(&target[offset], use, bufSize - offset);
821 *pos = strlen(target);
822 if (append)
823 target[(*pos)++] = ' ';
824 target[*pos] = '\0';
825
826 return true;
827 }
828
829 return false;
830}
831
833{
834 int i;
835
836 for (i = 0; i < csi.numGTs; i++) {
837 const gametype_t* gt = &csi.gts[i];
838 if (Q_streq(gt->id, sv_gametype->string)) {
839 int j;
840 const cvarlist_t* list;
841 if (sv_dedicated->integer)
842 Com_Printf("set gametype to: %s\n", gt->id);
843 for (j = 0, list = gt->cvars; j < gt->num_cvars; j++, list++) {
844 Cvar_Set(list->name, "%s", list->value);
845 if (sv_dedicated->integer)
846 Com_Printf(" %s = %s\n", list->name, list->value);
847 }
848 /*Com_Printf("Make sure to restart the map if you switched during a game\n");*/
849 break;
850 }
851 }
852
853 if (i == csi.numGTs)
854 Com_Printf("Can't set the gametype - unknown value for cvar gametype: '%s'\n", sv_gametype->string);
855}
856
857static void Com_GameTypeList_f (void)
858{
859 Com_Printf("Available gametypes:\n");
860 for (int i = 0; i < csi.numGTs; i++) {
861 int j;
862 const gametype_t* gt = &csi.gts[i];
863 const cvarlist_t* list;
864
865 Com_Printf("%s\n", gt->id);
866
867 for (j = 0, list = gt->cvars; j < gt->num_cvars; j++, list++)
868 Com_Printf(" %s = %s\n", list->name, list->value);
869 }
870}
871
878{
880 return false;
881
882 /* CS_TILES and CS_POSITIONS can stretch over multiple configstrings,
883 * so don't access the middle parts. */
884 if (index > CS_TILES && index < CS_POSITIONS)
885 return false;
887 return false;
888
889 return true;
890}
891
892#ifdef DEBUG
896static void Com_DebugHelp_f (void)
897{
898 Cvar_PrintDebugCvars();
899
900 Cmd_PrintDebugCommands();
901}
902
906static void Com_DebugError_f (void)
907{
908 if (Cmd_Argc() == 3) {
909 const char* errorType = Cmd_Argv(1);
910 if (Q_streq(errorType, "ERR_DROP"))
911 Com_Error(ERR_DROP, "%s", Cmd_Argv(2));
912 else if (Q_streq(errorType, "ERR_FATAL"))
913 Com_Error(ERR_FATAL, "%s", Cmd_Argv(2));
914 else if (Q_streq(errorType, "ERR_DISCONNECT"))
916 }
917 Com_Printf("Usage: %s <ERR_FATAL|ERR_DROP|ERR_DISCONNECT> <msg>\n", Cmd_Argv(0));
918}
919#endif
920
921
922typedef struct debugLevel_s {
923 const char* str;
926
927static const debugLevel_t debugLevels[] = {
928 {"DEBUG_ALL", DEBUG_ALL},
929 {"DEBUG_ENGINE", DEBUG_ENGINE},
930 {"DEBUG_SHARED", DEBUG_SHARED},
931 {"DEBUG_SYSTEM", DEBUG_SYSTEM},
932 {"DEBUG_COMMANDS", DEBUG_COMMANDS},
933 {"DEBUG_CLIENT", DEBUG_CLIENT},
934 {"DEBUG_EVENTSYS", DEBUG_EVENTSYS},
935 {"DEBUG_ROUTING", DEBUG_ROUTING},
936 {"DEBUG_SERVER", DEBUG_SERVER},
937 {"DEBUG_GAME", DEBUG_GAME},
938 {"DEBUG_RENDERER", DEBUG_RENDERER},
939 {"DEBUG_SOUND", DEBUG_SOUND},
940
941 {nullptr, 0}
942};
943
944static void Com_DeveloperSet_f (void)
945{
946 const int oldValue = Cvar_GetInteger("developer");
947 int newValue = oldValue;
948 int i = 0;
949
950 if (Cmd_Argc() == 2) {
951 const char* debugLevel = Cmd_Argv(1);
952 while (debugLevels[i].str) {
953 if (Q_streq(debugLevel, debugLevels[i].str)) {
954 if (oldValue & debugLevels[i].debugLevel) /* if it's already set... */
955 newValue &= ~debugLevels[i].debugLevel; /* ...reset it. */
956 else
957 newValue |= debugLevels[i].debugLevel;
958 break;
959 }
960 i++;
961 }
962 if (!debugLevels[i].str) {
963 Com_Printf("No valid debug mode parameter\n");
964 return;
965 }
966 Cvar_SetValue("developer", newValue);
967 Com_Printf("Currently selected debug print levels\n");
968 i = 0;
969 while (debugLevels[i].str) {
970 if (newValue & debugLevels[i].debugLevel)
971 Com_Printf("* %s\n", debugLevels[i].str);
972 i++;
973 }
974 } else {
975 Com_Printf("Usage: %s <debug_level>\n", Cmd_Argv(0));
976 Com_Printf(" valid debug_levels are:\n");
977 while (debugLevels[i].str) {
978 Com_Printf(" * %s\n", debugLevels[i].str);
979 i++;
980 }
981 }
982}
983
984#ifndef DEDICATED_ONLY
988static bool Com_CvarCheckMaxFPS (cvar_t* cvar)
989{
990 /* don't allow setting maxfps too low (or game could stop responding) */
991 return Cvar_AssertValue(cvar, 10, 1000, true);
992}
993#endif
994
999{
1000 ScopedFile f;
1001
1003 if (!f.file()) {
1004 Com_Printf("Couldn't write %s.\n", filename);
1005 return;
1006 }
1007
1008 FS_Printf(&f, "// generated by ufo, do not modify\n");
1009 FS_Printf(&f, "// variables\n");
1011 FS_Printf(&f, "// aliases\n");
1013 Com_Printf("Wrote %s.\n", filename);
1014}
1015
1016void Com_SetRandomSeed (unsigned int seed)
1017{
1018 srand(seed);
1019 /*Com_Printf("setting random seed to %i\n", seed);*/
1020}
1021
1022const char* Com_ByteToBinary (byte x)
1023{
1024 static char buf[9];
1025 const int mask = 1 << 7;
1026 char* b = buf;
1027
1028 for (int cnt = 1; cnt <= 8; ++cnt) {
1029 *b++ = ((x & mask) == 0) ? '0' : '1';
1030 x <<= 1;
1031 if (cnt == 8)
1032 *b++ = '\0';
1033 }
1034
1035 return buf;
1036}
1037
1038const char* Com_UnsignedIntToBinary (uint32_t x)
1039{
1040 static char buf[37];
1041 const int mask = 1 << 31;
1042 char* b = buf;
1043
1044 for (int cnt = 1; cnt <= 32; ++cnt) {
1045 *b++ = ((x & mask) == 0) ? '0' : '1';
1046 x <<= 1;
1047 if (cnt % 8 == 0 && cnt != 32)
1048 *b++ = ' ';
1049 if (cnt == 32)
1050 *b++ = '\0';
1051 }
1052
1053 return buf;
1054}
1055
1059static void Com_WriteConfig_f (void)
1060{
1061 char filename[MAX_QPATH];
1062
1063 if (Cmd_Argc() != 2) {
1064 Com_Printf("Usage: %s <filename>\n", Cmd_Argv(0));
1065 return;
1066 }
1067
1068 Q_strncpyz(filename, Cmd_Argv(1), sizeof(filename));
1069 Com_DefaultExtension(filename, sizeof(filename), ".cfg");
1071}
1072
1073static void Cbuf_Execute_timer (int now, void* data)
1074{
1075 Cbuf_Execute();
1076}
1077
1079{
1080 vPrintfPtr = func;
1081}
1082
1084{
1085 return vPrintfPtr;
1086}
1087
1095void Qcommon_Init (int argc, char** argv)
1096{
1097 logfile_active = nullptr;
1098 developer = nullptr;
1099
1101
1102 /* random seed */
1103 Com_SetRandomSeed(time(nullptr));
1104
1105 Mem_Init();
1106 com_aliasSysPool = Mem_CreatePool("Common: Alias system for commands and enums");
1107 com_cmdSysPool = Mem_CreatePool("Common: Command system");
1108 com_cmodelSysPool = Mem_CreatePool("Common: Collision model");
1109 com_cvarSysPool = Mem_CreatePool("Common: Cvar system");
1110 com_fileSysPool = Mem_CreatePool("Common: File system");
1111 com_genericPool = Mem_CreatePool("Generic");
1112 com_networkPool = Mem_CreatePool("Network");
1113
1114 try {
1115 OBJZERO(csi);
1116
1117 /* prepare enough of the subsystems to handle
1118 * cvar and command buffer management */
1119 Com_InitArgv(argc, argv);
1120
1121 Swap_Init();
1122 Cbuf_Init();
1123
1124 Cmd_Init();
1125 Cvar_Init();
1126
1127 Key_Init();
1128
1129 /* we need to add the early commands twice, because
1130 * a basedir needs to be set before executing
1131 * config files, but we want other parms to override
1132 * the settings of the config files */
1133 Cbuf_AddEarlyCommands(false);
1134 Cbuf_Execute();
1135
1136 FS_InitFilesystem(true);
1137
1138 Cbuf_AddText("exec default.cfg\n");
1139#ifdef DEDICATED_ONLY
1140 Cbuf_AddText("exec dedconfig.cfg\n");
1141#else
1142 Cbuf_AddText("exec config.cfg\n");
1143#endif
1144
1146 Cbuf_Execute();
1147
1148 Com_SetRenderModified(false);
1150
1151 /* init commands and vars */
1152 Cmd_AddCommand("saveconfig", Com_WriteConfig_f, "Write the configuration to file");
1153 Cmd_AddCommand("gametypelist", Com_GameTypeList_f, "List all available multiplayer game types");
1154#ifdef DEBUG
1155 Cmd_AddCommand("debug_help", Com_DebugHelp_f, "Show some debugging help");
1156 Cmd_AddCommand("debug_error", Com_DebugError_f, "Just throw a fatal error to test error shutdown procedures");
1157#endif
1158 Cmd_AddCommand("setdeveloper", Com_DeveloperSet_f, "Set the developer cvar to only get the debug output you want");
1159
1160 developer = Cvar_Get("developer", "0", 0, "Activate developer output to logfile and gameconsole");
1161#ifdef DEBUG
1162 logfile_active = Cvar_Get("logfile", "2", 0, "0 = deactivate logfile, 1 = write normal logfile, 2 = flush on every new line, 3 = always append to existing file");
1163#else
1164 logfile_active = Cvar_Get("logfile", "1", 0, "0 = deactivate logfile, 1 = write normal logfile, 2 = flush on every new line, 3 = always append to existing file");
1165#endif
1166 sv_gametype = Cvar_Get("sv_gametype", "fight1on1", CVAR_ARCHIVE | CVAR_SERVERINFO, "Sets the multiplayer gametype - see gametypelist command for a list of all gametypes");
1167 http_proxy = Cvar_Get("http_proxy", "", CVAR_ARCHIVE, "Use this proxy for http transfers");
1168 http_timeout = Cvar_Get("http_timeout", "3", CVAR_ARCHIVE, "Http connection and read timeout");
1170 masterserver_url = Cvar_Get("masterserver_url", MASTER_SERVER, CVAR_ARCHIVE, "URL of UFO:AI masterserver");
1171#ifdef DEDICATED_ONLY
1172 sv_dedicated = Cvar_Get("sv_dedicated", "1", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
1173 /* don't allow to override this from commandline of config */
1174 Cvar_ForceSet("sv_dedicated", "1");
1175#else
1176 sv_dedicated = Cvar_Get("sv_dedicated", "0", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
1177
1178 /* set this to false for client - otherwise Qcommon_Frame would set the initial values to multiplayer */
1179 sv_gametype->modified = false;
1180
1181 s_language = Cvar_Get("s_language", "", CVAR_ARCHIVE, "Game language - full language string e.g. en_EN.UTF-8");
1182 s_language->modified = false;
1183 cl_maxfps = Cvar_Get("cl_maxfps", "50", CVAR_ARCHIVE);
1185#endif
1186
1187 // 5 is an i7 with a medium gfx-card
1188 // 3 dual core with 2 GB
1189 // 2 EeePc with 1 GB
1190 // 1 smartphone
1191 const char* hwclassVal = "5";
1192#ifdef __ANDROID__
1194 hwclassVal = "1";
1195#endif
1196 hwclass = Cvar_Get("hwclass", hwclassVal, 0, "Defines the hardware class of this machine. 1 is the lowest, 5 is the highest.");
1197
1198 const char* s = va("UFO: Alien Invasion %s %s %s %s", UFO_VERSION, CPUSTRING, "May 14 2025", BUILDSTRING);
1199 Cvar_Get("version", s, CVAR_NOSET, "Full version string");
1200 Cvar_Get("ver", UFO_VERSION, CVAR_SERVERINFO | CVAR_NOSET, "Version number");
1201
1202 if (sv_dedicated->integer)
1203 Cmd_AddCommand("quit", Com_Quit, "Quits the game");
1204
1205#ifdef COMPILE_UFO
1206 Mem_InitCallbacks();
1207#endif
1208 Sys_Init();
1209
1210 NET_Init();
1211
1212#ifndef NO_HTTP
1213 curl_global_init(CURL_GLOBAL_NOTHING);
1214 Com_Printf("%s initialized.\n", curl_version());
1215#endif
1216
1217 SV_Init();
1218
1219 /* e.g. init the client hunk that is used in script parsing */
1220 CL_Init();
1221
1223#ifndef DEDICATED_ONLY
1224 Cbuf_AddText("exec keys.cfg\n");
1225#endif
1226
1227 if (!sv_dedicated->integer)
1228 Cbuf_AddText("init\n");
1229 else
1230 Cbuf_AddText("dedicated_start\n");
1231 Cbuf_Execute();
1232
1234
1235 /* add + commands from command line
1236 * if the user didn't give any commands, run default action */
1237 if (Cbuf_AddLateCommands()) {
1238 /* the user asked for something explicit
1239 * so drop the loading plaque */
1241 }
1242
1243 const cvar_t* com_pipefile = Cvar_Get("com_pipefile", "", CVAR_ARCHIVE, "Filename of the pipe that is used to send commands to the game");
1244 if (com_pipefile->string[0] != '\0') {
1245 FS_CreateOpenPipeFile(com_pipefile->string, &pipefile);
1246 }
1247
1248 CL_InitAfter();
1249
1250 /* Check memory integrity */
1252
1253#ifndef DEDICATED_ONLY
1254 if (!sv_dedicated->integer) {
1255 Schedule_Timer(cl_maxfps, &CL_Frame, nullptr, nullptr);
1256 Schedule_Timer(Cvar_Get("cl_slowfreq", "10", 0, nullptr), &CL_SlowFrame, nullptr, nullptr);
1257
1258 /* now hide the console */
1259 Sys_ShowConsole(false);
1260 }
1261#endif
1262
1263 Schedule_Timer(Cvar_Get("sv_freq", "10", CVAR_NOSET, nullptr), &SV_Frame, nullptr, nullptr);
1264
1266 Schedule_Timer(Cvar_Get("cbuf_freq", "10", 0, nullptr), &Cbuf_Execute_timer, nullptr, nullptr);
1267
1268 Com_Printf("====== UFO Initialized ======\n");
1269 Com_Printf("=============================\n");
1270 } catch (comDrop_t const&) {
1271 Sys_Error("Error during initialization");
1272 }
1273}
1274
1279{
1280 if (pipefile.f == nullptr)
1281 return;
1282
1283 char buffer[MAX_STRING_CHARS] = { "" };
1284 const int read = FS_Read2(buffer, sizeof(buffer), &pipefile, false);
1285 if (read > 0)
1286 Cmd_ExecuteString("%s", buffer);
1287}
1288
1289static void tick_timer (int now, void* data)
1290{
1291 struct timer* timer = (struct timer*)data;
1292 const int old_interval = timer->interval;
1293
1294 /* Compute and store the lateness, updating the total */
1295 const int lateness = Sys_Milliseconds() - now;
1298 timer->total_lateness += lateness;
1301
1302 /* Is it time to check the mean yet? */
1303 timer->next_check--;
1304 if (timer->next_check <= 0) {
1305 const int mean = timer->total_lateness / TIMER_LATENESS_HISTORY;
1306
1307 /* We use a saturating counter to damp the adjustment */
1308
1309 /* When we stay above the high water mark, increase the interval */
1310 if (mean > TIMER_LATENESS_HIGH)
1312 else
1313 timer->checks_high = std::max(0, timer->checks_high - 1);
1314
1316 timer->interval += 2;
1317
1318 /* When we stay below the low water mark, decrease the interval */
1319 if (mean < TIMER_LATENESS_LOW)
1321 else
1322 timer->checks_low = std::max(0, timer->checks_low - 1);
1323
1325 timer->interval -= 1;
1326
1327 /* Note that we slow the timer more quickly than we speed it up,
1328 * so it should tend to settle down in the vicinity of the low
1329 * water mark */
1330
1332 }
1333
1334 timer->interval = std::max(timer->interval, 1000 / timer->min_freq->integer);
1335
1336 if (timer->interval != old_interval)
1337 Com_DPrintf(DEBUG_ENGINE, "Adjusted timer on %s to interval %d\n", timer->min_freq->name, timer->interval);
1338
1339 try {
1340 timer->func(now, timer->data);
1341 } catch (comDrop_t const&) {
1342 }
1343
1344 /* We correct for the lateness of this frame. We do not correct for
1345 * the time consumed by this frame - that's billed to the lateness
1346 * of future frames (so that the automagic slowdown can work) */
1347 Schedule_Event(now + lateness + timer->interval, &tick_timer, nullptr, nullptr, timer);
1348}
1349
1350static void Schedule_Timer (cvar_t* freq, event_func* func, event_check_func* check, void* data)
1351{
1352 struct timer* const timer = Mem_PoolAllocType(struct timer, com_genericPool);
1353 timer->min_freq = freq;
1354 timer->interval = 1000 / freq->integer;
1355 timer->next_lateness = 0;
1356 timer->total_lateness = 0;
1358 timer->checks_high = 0;
1359 timer->checks_low = 0;
1360 timer->func = func;
1361 timer->data = data;
1362 for (int i = 0; i < TIMER_LATENESS_HISTORY; i++)
1363 timer->recent_lateness[i] = 0;
1364
1366}
1367
1381{
1383 event->when = when;
1384 event->func = func;
1385 event->check = check;
1386 event->clean = clean;
1387 event->data = data;
1388 event->delayFollowing = 0; /* Delay the following events of the same type (same event func) by the given amount of milliseconds if the check function returned false. */
1389 event->delay = nullptr;
1390
1391 eventQueue.insert(event);
1392
1393 return event;
1394}
1395
1401static size_t Delay_Events (int now, EventPriorityQueue::iterator i)
1402{
1403 const ScheduleEventPtr event = *i;
1404 EventPriorityQueue reOrder;
1405 EventPriorityQueue::iterator itEnd = eventQueue.end();
1406 for (; i != itEnd;) {
1407 ScheduleEventPtr tmpEvent = *i;
1408 if (tmpEvent->func != event->func) {
1409 ++i;
1410 continue;
1411 }
1412 if (tmpEvent->delay != nullptr && !tmpEvent->delay(now, tmpEvent->data)){
1413 ++i;
1414 continue;
1415 }
1416
1417 tmpEvent->when += event->delayFollowing;
1418 reOrder.insert(tmpEvent);
1419 eventQueue.erase(i++);
1420 }
1421 for (EventPriorityQueue::iterator r = reOrder.begin(); r != reOrder.end(); ++r) {
1422 eventQueue.insert(*r);
1423 }
1424 return reOrder.size();
1425}
1426
1434{
1435 for (EventPriorityQueue::iterator i = eventQueue.begin(); i != eventQueue.end(); ++i) {
1436 ScheduleEventPtr event = *i;
1437 if (event->when > now)
1438 break;
1439
1440 if (event->check == nullptr || event->check(now, event->data)) {
1441 eventQueue.erase(i);
1442 return event;
1443 }
1444
1445 /* delay all other events if this one is blocked */
1446 if (event->delayFollowing > 0) {
1447 if (Delay_Events(now, i) > 0) {
1448 if (event->notifyDelay != nullptr) {
1449 event->notifyDelay(now, event->notifyDelayUserData, event->delayFollowing);
1450 }
1451 break;
1452 }
1453 }
1454 }
1455 return ScheduleEventPtr();
1456}
1457
1465{
1466 int filtered = 0;
1467
1468 assert(filter);
1469
1470 for (EventPriorityQueue::iterator i = eventQueue.begin(); i != eventQueue.end();) {
1471 ScheduleEventPtr event = *i;
1472 const bool keep = filter(event->when, event->func, event->check, event->data);
1473 if (keep) {
1474 ++i;
1475 continue;
1476 }
1477
1478 if (event->clean != nullptr)
1479 event->clean(event->data);
1480
1481 EventPriorityQueue::iterator removeIter = i++;
1482 eventQueue.erase(removeIter);
1483 filtered++;
1484 }
1485
1486 return filtered;
1487}
1488
1498static bool Event_FilterAll (int when, event_func* func, event_check_func* check, void* data)
1499{
1500 return false;
1501}
1502
1511void Qcommon_Frame (void)
1512{
1513 try {
1514 /* If the next event is due... */
1516 if (event) {
1517 /* Dispatch the event */
1518 event->func(event->when, event->data);
1519 }
1520 } catch (comRestart_t const& restart) {
1521 SV_Shutdown("Restart.", false);
1522 CL_Shutdown();
1525 if (restart.gamedir != nullptr) {
1526 const char* restartArgv[] = {"", "+set", "fs_gamedir", restart.gamedir};
1527 Qcommon_Init(4, const_cast<char** >(restartArgv));
1528 } else {
1529 Qcommon_Init(0, nullptr);
1530 }
1531 } catch (comDrop_t const&) {
1532 return;
1533 }
1534
1535 /* Now we spend time_to_next milliseconds working on whatever
1536 * IO is ready (but always try at least once, to make sure IO
1537 * doesn't stall) */
1538 int time_to_next;
1539 do {
1540 time_to_next = !eventQueue.empty() ? (eventQueue.begin()->get()->when - Sys_Milliseconds()) : 1000;
1541 if (time_to_next < 0)
1542 time_to_next = 0;
1543
1544 NET_Wait(time_to_next);
1545 } while (time_to_next > 0);
1546}
1547
1556{
1557#ifdef COMPILE_UFO
1558 Mem_ShutdownCallbacks();
1559#endif
1560 HTTP_Cleanup();
1561
1562 FS_Shutdown();
1563 Cvar_Shutdown();
1564 Cmd_Shutdown();
1565 NET_Shutdown();
1566 Mem_Shutdown();
1567 Com_Shutdown();
1568}
void Sys_ShowConsole(bool show)
void Sys_ConsoleOutput(const char *string)
void Sys_Init(void)
void Sys_Backtrace(void)
On platforms supporting it, print a backtrace.
void Sys_Quit(void)
void Swap_Init(void)
Definition byte.cpp:31
void Con_Print(const char *txt)
Handles cursor positioning, line wrapping, etc All console printing must go through this in order to ...
void FS_CloseFile(qFILE *f)
bool buttons[16]
void Key_Init(void)
Definition cl_keys.cpp:776
void CL_Drop(void)
Ensures the right menu cvars are set after error drop or map change.
Definition cl_main.cpp:167
void CL_SlowFrame(int now, void *data)
Definition cl_main.cpp:1108
void CL_Frame(int now, void *data)
Definition cl_main.cpp:1047
void CL_Shutdown(void)
Saves configuration file and shuts the client systems down.
Definition cl_main.cpp:1219
void CL_InitAfter(void)
Init function for clients - called after menu was initialized and ufo-scripts were parsed.
Definition cl_main.cpp:737
void CL_Init(void)
Definition cl_main.cpp:1141
void SCR_EndLoadingPlaque(void)
bool operator()(const ScheduleEventPtr &e1, const ScheduleEventPtr &e2) const
Definition common.cpp:97
const char * gamedir
Definition common.h:248
cvar_t * s_language
Definition common.cpp:54
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
Definition cmd.cpp:1007
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition cmd.cpp:516
void Cmd_WriteAliases(qFILE *f)
Write lines containing "aliasa alias value" for all aliases with the archive flag set to true.
Definition cmd.cpp:454
void Cbuf_Execute(void)
Pulls off terminated lines of text from the command buffer and sends them through Cmd_ExecuteString...
Definition cmd.cpp:214
int Cmd_CompleteCommandParameters(const char *command, const char *partial, const char **match)
Unix like tab completion for console commands parameters.
Definition cmd.cpp:903
void Cbuf_AddEarlyCommands(bool clear)
Adds command line parameters as script statements Commands lead with a +, and continue until another ...
Definition cmd.cpp:275
void Cmd_Init(void)
Definition cmd.cpp:1127
void Cbuf_Init(void)
allocates an initial text buffer that will grow as needed
Definition cmd.cpp:109
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition cmd.cpp:505
void Cmd_AddCommand(const char *cmdName, xcommand_t function, const char *desc)
Add a new command to the script interface.
Definition cmd.cpp:744
bool Cbuf_AddLateCommands(void)
Adds command line parameters as script statements.
Definition cmd.cpp:298
void Cbuf_AddText(const char *format,...)
Adds command text at the end of the buffer.
Definition cmd.cpp:126
void Cmd_Shutdown(void)
Definition cmd.cpp:1145
int Cmd_CompleteCommand(const char *partial, const char **match)
Unix like tab completion for console commands.
Definition cmd.cpp:924
static void Com_WriteConfig_f(void)
Write the config file to a specific name.
Definition common.cpp:1059
const char * Com_ByteToBinary(byte x)
Definition common.cpp:1022
static struct net_stream * rd_stream
Definition common.cpp:342
cvar_t * http_proxy
Definition common.cpp:47
bool Com_ConsoleCompleteCommand(const char *s, char *target, size_t bufSize, uint32_t *pos, uint32_t offset)
Console completion for command and variables.
Definition common.cpp:734
#define TIMER_CHECK_LAG
Definition common.cpp:76
memPool_t * com_cmdSysPool
Definition common.cpp:68
csi_t csi
Definition common.cpp:39
static EventPriorityQueue eventQueue
Definition common.cpp:103
int Com_Argc(void)
Returns the script commandline argument count.
Definition common.cpp:600
#define TIMER_CHECK_INTERVAL
Definition common.cpp:75
void Qcommon_Frame(void)
This is the function that is called directly from main().
Definition common.cpp:1511
cvar_t * sys_os
Definition common.cpp:61
#define TIMER_LATENESS_LOW
Definition common.cpp:78
static const debugLevel_t debugLevels[]
Definition common.cpp:927
memPool_t * com_cvarSysPool
Definition common.cpp:70
#define MAX_NUM_ARGVS
Definition common.cpp:37
static qFILE pipefile
Definition common.cpp:65
void Com_SetServerState(int state)
Definition common.cpp:587
cvar_t * sys_priority
Definition common.cpp:59
cvar_t * port
Definition common.cpp:58
ScheduleEventPtr Dequeue_Event(int now)
Finds and returns the first event in the event_queue that is due. If the event has a check function,...
Definition common.cpp:1433
static const char * com_argv[MAX_NUM_ARGVS+1]
Definition common.cpp:42
static void Schedule_Timer(cvar_t *freq, event_func *func, event_check_func *check, void *data)
Definition common.cpp:1350
#define TIMER_LATENESS_HIGH
Definition common.cpp:77
void Com_ReadFromPipe(void)
Read whatever is in com_pipefile, if anything, and execute it.
Definition common.cpp:1278
void Com_vPrintf(const char *fmt, va_list ap)
Definition common.cpp:380
cvar_t * sys_affinity
Definition common.cpp:60
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
int Com_ServerState(void)
Check whether we are the server or have a singleplayer tactical mission.
Definition common.cpp:578
#define MACRO_CVAR_ID_LENGTH
Definition common.cpp:640
cvar_t * sv_dedicated
Definition common.cpp:51
cvar_t * hwclass
Definition common.cpp:62
static bool Com_CvarCheckMaxFPS(cvar_t *cvar)
Watches that the cvar cl_maxfps is never getting lower than 10.
Definition common.cpp:988
static int com_argc
Definition common.cpp:41
void Com_Quit(void)
Definition common.cpp:551
void Qcommon_Init(int argc, char **argv)
Init function.
Definition common.cpp:1095
static void Com_DeveloperSet_f(void)
Definition common.cpp:944
static vPrintfPtr_t vPrintfPtr
Definition common.cpp:44
cvar_t * http_timeout
Definition common.cpp:48
float Com_GrenadeTarget(const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0)
Calculates parabola-type shot.
Definition common.cpp:273
void Com_WriteConfigToFile(const char *filename)
Definition common.cpp:998
vPrintfPtr_t Qcommon_GetPrintFunction(void)
Definition common.cpp:1083
static const char * libNameSuffix[]
Dynamic library filename suffix list.
Definition common.cpp:110
void * Com_LoadLibrary(const char *path, const char *prefix)
Attempts to load a library using a filename suffix list.
Definition common.cpp:126
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
void Com_SetGameType(void)
Definition common.cpp:832
memPool_t * com_aliasSysPool
Definition common.cpp:67
const char * Com_UnsignedIntToBinary(uint32_t x)
Definition common.cpp:1038
static void Com_GameTypeList_f(void)
Definition common.cpp:857
cvar_t * developer
Definition common.cpp:46
void Com_SetRandomSeed(unsigned int seed)
Definition common.cpp:1016
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
memPool_t * com_networkPool
Definition common.cpp:73
const char * Com_MacroExpandString(const char *text)
Expands strings with cvar values that are dereferenced by a '*cvar'.
Definition common.cpp:647
std::multiset< ScheduleEventPtr, CompareScheduleEvent > EventPriorityQueue
Definition common.cpp:102
static unsigned int rd_buffersize
Definition common.cpp:341
static void Com_InitArgv(int argc, char **argv)
Definition common.cpp:627
cvar_t * masterserver_url
Definition common.cpp:57
ScheduleEventPtr Schedule_Event(int when, event_func *func, event_check_func *check, event_clean_func *clean, void *data)
Schedules an event to run on or after the given time, and when its check function returns true.
Definition common.cpp:1380
int CL_FilterEventQueue(event_filter *filter)
Filters every event in the queue using the given function. Keeps all events for which the function re...
Definition common.cpp:1464
void Com_Drop(void)
Definition common.cpp:507
void Com_BeginRedirect(struct net_stream *stream, char *buffer, int buffersize)
Redirect packets/output from server to client.
Definition common.cpp:350
void Com_ClearArgv(int arg)
Reset com_argv entry to empty string.
Definition common.cpp:620
bool Com_CheckConfigStringIndex(int index)
Definition common.cpp:877
#define MAXPRINTMSG
Definition common.cpp:36
void Com_EndRedirect(void)
End the redirection of packets/output.
Definition common.cpp:367
static const char * consoleLogName
Definition common.cpp:49
static cvar_t * logfile_active
Definition common.cpp:50
static void tick_timer(int now, void *data)
Definition common.cpp:1289
cvar_t * sv_gametype
Definition common.cpp:56
static char * rd_buffer
Definition common.cpp:340
static size_t Delay_Events(int now, EventPriorityQueue::iterator i)
Delay the following events and return the amount of events delayed.
Definition common.cpp:1401
static qFILE logfile
Definition common.cpp:64
void Com_BreakIntoDebugger(void)
Definition common.cpp:512
static bool Event_FilterAll(int when, event_func *func, event_check_func *check, void *data)
Eventfilter that filter out all events.
Definition common.cpp:1498
memPool_t * com_genericPool
Definition common.cpp:72
void Qcommon_SetPrintFunction(vPrintfPtr_t func)
Definition common.cpp:1078
memPool_t * com_cmodelSysPool
Definition common.cpp:69
static void Cbuf_Execute_timer(int now, void *data)
Definition common.cpp:1073
memPool_t * com_fileSysPool
Definition common.cpp:71
static cvar_t * cl_maxfps
Definition common.cpp:53
#define TIMER_LATENESS_HISTORY
Definition common.cpp:79
const char * Com_Argv(int arg)
Returns an argument of script commandline.
Definition common.cpp:608
void Qcommon_Shutdown(void)
Definition common.cpp:1555
definitions common between client and server, but not game lib
void event_clean_func(void *data)
Definition common.h:310
void(* vPrintfPtr_t)(const char *fmt, va_list ap)
Definition common.h:287
void SV_Frame(int now, void *)
Definition sv_main.cpp:837
void Cvar_WriteVariables(qFILE *f)
appends lines containing "set variable value" for all variables with the archive flag set to true.
Definition cvar.cpp:868
SharedPtr< scheduleEvent_t > ScheduleEventPtr
Definition common.h:331
#define PORT_SERVER
Definition common.h:137
#define MASTER_SERVER
Definition common.h:124
void event_func(int now, void *data)
Definition common.h:302
#define CPUSTRING
Definition common.h:109
void SV_Shutdown(const char *finalmsg, bool reconnect)
Called when each game quits, before Sys_Quit or Sys_Error.
Definition sv_main.cpp:1042
#define ERR_DROP
Definition common.h:211
bool event_check_func(int now, void *data)
Definition common.h:303
#define MAXCMDLINE
Definition common.h:285
void SV_Clear(void)
Cleanup when the whole game process is shutting down.
Definition sv_main.cpp:1030
#define UFO_VERSION
Definition common.h:36
void SV_Init(void)
Only called once at startup, not for each game.
Definition sv_main.cpp:960
#define BUILDSTRING
Definition common.h:121
#define ERR_FATAL
Definition common.h:210
bool event_filter(int when, event_func *func, event_check_func *check, void *data)
Definition common.h:309
cvar_t * Cvar_ForceSet(const char *varName, const char *value)
Will set the variable even if NOSET or LATCH.
Definition cvar.cpp:604
void Com_SetRenderModified(bool modified)
Definition cvar.cpp:66
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition cvar.cpp:671
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition cvar.cpp:615
bool Cvar_SetCheckFunction(const char *varName, bool(*check)(cvar_t *cvar))
Set a checker function for cvar values.
Definition cvar.cpp:139
int Cvar_GetInteger(const char *varName)
Returns the int value of a cvar.
Definition cvar.cpp:194
bool Cvar_AssertValue(cvar_t *cvar, float minVal, float maxVal, bool shouldBeIntegral)
Checks cvar values.
Definition cvar.cpp:161
void Cvar_Shutdown(void)
Definition cvar.cpp:1100
void Cvar_Init(void)
Reads in all archived cvars.
Definition cvar.cpp:1087
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
Definition cvar.cpp:342
const char * Cvar_GetString(const char *varName)
Returns the value of cvar as string.
Definition cvar.cpp:210
void Com_SetUserinfoModified(bool modified)
Definition cvar.cpp:56
int Cvar_CompleteVariable(const char *partial, const char **match)
Unix like tab completion for console variables.
Definition cvar.cpp:258
#define CVAR_SERVERINFO
Definition cvar.h:42
#define CVAR_ARCHIVE
Definition cvar.h:40
#define CVAR_NOSET
Definition cvar.h:43
#define ERR_DISCONNECT
Definition defines.h:112
#define DEBUG_SYSTEM
Definition defines.h:57
#define DEBUG_EVENTSYS
Definition defines.h:64
#define DEBUG_ALL
Definition defines.h:54
#define DEBUG_CLIENT
Definition defines.h:59
#define DEBUG_COMMANDS
Definition defines.h:58
#define DEBUG_SOUND
Definition defines.h:63
#define DEBUG_ENGINE
Definition defines.h:56
#define DIST_EPSILON
Definition defines.h:377
#define DEBUG_RENDERER
Definition defines.h:62
#define DEBUG_GAME
Definition defines.h:61
#define DEBUG_SHARED
Definition defines.h:55
#define MAX_TOKEN_CHARS
Definition defines.h:372
#define DEBUG_SERVER
Definition defines.h:60
#define DEBUG_ROUTING
Definition defines.h:66
#define MAX_STRING_CHARS
Definition defines.h:90
int FS_Read2(void *buffer, int len, qFILE *f, bool failOnEmptyRead)
Read a file into a given buffer in memory.
Definition files.cpp:327
int FS_Printf(qFILE *f, const char *msg,...)
Can print chunks for 1024 chars into a file.
Definition files.cpp:1497
void FS_InitFilesystem(bool writeToHomeDir)
Definition files.cpp:890
void FS_RemoveFile(const char *osPath)
Definition files.cpp:1692
int FS_Write(const void *buffer, int len, qFILE *f)
Properly handles partial writes.
Definition files.cpp:1513
void FS_Shutdown(void)
Cleanup function.
Definition files.cpp:1604
void FS_CreateOpenPipeFile(const char *filename, qFILE *f)
Definition files.cpp:47
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition files.cpp:162
const char * FS_Gamedir(void)
Called to find where to write a file (savegames, etc).
Definition files.cpp:68
#define MAX_OSPATH
Definition filesys.h:44
void FS_ExecAutoexec(void)
#define MAX_QPATH
Definition filesys.h:40
@ FILE_APPEND
Definition filesys.h:111
@ FILE_WRITE
Definition filesys.h:111
level_locals_t level
Definition g_main.cpp:38
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
void HTTP_Cleanup(void)
UFO is exiting or we're changing servers. Clean up.
Definition http.cpp:406
voidpf stream
Definition ioapi.h:42
const char * filename
Definition ioapi.h:41
voidpf void * buf
Definition ioapi.h:42
voidpf uLong offset
Definition ioapi.h:45
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
Definition mathlib.cpp:434
void VectorNormalizeFast(vec3_t v)
fast vector normalize routine that does not check to make sure that length != 0, nor does it return l...
Definition mathlib.cpp:762
#define torad
Definition mathlib.h:50
void Mem_Init(void)
Definition mem.cpp:506
void Mem_Shutdown(void)
Definition mem.cpp:518
#define Mem_CreatePool(name)
Definition mem.h:32
#define Mem_PoolAllocType(type, pool)
Definition mem.h:43
#define Mem_CheckGlobalIntegrity()
Definition mem.h:54
void NET_Init(void)
Definition net.cpp:305
void NET_Shutdown(void)
Definition net.cpp:337
void NET_Wait(int timeout)
Definition net.cpp:423
void NET_OOB_Printf(struct net_stream *s, const char *format,...)
Out of band print.
Definition netpack.cpp:548
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Definition parse.cpp:107
Shared parsing functions.
#define CS_TILES
Definition q_shared.h:325
#define SV_CMD_PRINT
Definition q_shared.h:593
#define CS_POSITIONS
Definition q_shared.h:326
#define GRAVITY
Definition q_shared.h:276
#define MAX_CONFIGSTRINGS
Definition q_shared.h:330
#define CS_MODELS
Definition q_shared.h:327
QGL_EXTERN GLuint GLchar GLuint * len
Definition r_gl.h:99
QGL_EXTERN GLuint count
Definition r_gl.h:99
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLsizei const GLvoid * data
Definition r_gl.h:89
QGL_EXTERN GLuint index
Definition r_gl.h:110
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei bufSize
Definition r_gl.h:110
void Com_ParseScripts(bool onlyServer)
Definition scripts.cpp:3619
void Com_Shutdown(void)
Definition scripts.cpp:3732
Main server include file.
server_state_t SV_GetServerState(void)
Definition sv_user.cpp:312
server_state_t
Definition server.h:95
@ ss_restart
Definition server.h:97
@ ss_dead
Definition server.h:96
serverInstanceGame_t * sv
Definition sv_init.cpp:36
#define Q_streq(a, b)
Definition shared.h:136
#define DOUBLEQUOTE(x)
Definition shared.h:90
#define OBJZERO(obj)
Definition shared.h:178
#define lengthof(x)
Definition shared.h:105
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
void Com_DefaultExtension(char *path, size_t len, const char *extension)
Sets a default extension if there is none.
Definition shared.cpp:297
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition shared.cpp:535
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition shared.cpp:475
void Com_MakeTimestamp(char *ts, const size_t tslen)
Creates a timestamp with date and time at the specified location.
Definition shared.cpp:352
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition shared.cpp:410
The csi structure is the client-server-information structure which contains all the static data neede...
Definition q_shared.h:515
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition cvar.h:71
int integer
Definition cvar.h:81
char * string
Definition cvar.h:73
char * name
Definition cvar.h:72
char value[MAX_VAR]
Definition q_shared.h:338
char name[MAX_VAR]
Definition q_shared.h:337
const char * str
Definition common.cpp:923
cvarlist_t cvars[MAX_CVARLISTINGAMETYPE]
Definition q_shared.h:344
char id[MAX_VAR]
Definition q_shared.h:342
event_delay_func * delay
Called when the check failed and we have to delay events in the queue.
Definition common.h:324
void * data
Definition common.h:328
event_func * func
Definition common.h:315
cvar_t * min_freq
Definition common.cpp:82
event_func * func
Definition common.cpp:91
int next_lateness
Definition common.cpp:85
int total_lateness
Definition common.cpp:86
int interval
Definition common.cpp:83
void * data
Definition common.cpp:92
int recent_lateness[TIMER_LATENESS_HISTORY]
Definition common.cpp:84
int next_check
Definition common.cpp:87
int checks_low
Definition common.cpp:89
int checks_high
Definition common.cpp:88
System specific stuff.
void Sys_Breakpoint(void)
void Sys_InitSignals(void)
int Sys_Milliseconds(void)
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorSubtract(a, b, dest)
Definition vector.h:45
#define VectorScale(in, scale, out)
Definition vector.h:79