UFO: Alien Invasion
common.cpp
Go to the documentation of this file.
1
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
64
67
75
76#define TIMER_CHECK_INTERVAL 100
77#define TIMER_CHECK_LAG 3
78#define TIMER_LATENESS_HIGH 200
79#define TIMER_LATENESS_LOW 50
80#define TIMER_LATENESS_HISTORY 32
81
82struct timer {
91
93 void* data;
94};
95
97public:
98 bool operator()(const ScheduleEventPtr& e1, const ScheduleEventPtr& e2) const {
99 return e1->when < e2->when;
100 }
101};
102
103typedef std::multiset<ScheduleEventPtr, CompareScheduleEvent> EventPriorityQueue;
105
106static void Schedule_Timer(cvar_t* freq, event_func* func, event_check_func* check, void* data);
107
108/*
109==============================================================================
110TARGETING FUNCTIONS
111==============================================================================
112*/
113
231float Com_GrenadeTarget (const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0)
232{
233 vec3_t delta;
234
235 /* calculate target distance and height */
236 const float h = at[2] - from[2];
237 VectorSubtract(at, from, delta);
238 delta[2] = 0;
239 const float d = VectorLength(delta);
240
241 /* check that it's not degenerate */
242 if (d == 0) {
243 return 0;
244 }
245
246 /* precalculate some useful values */
247 const float g = GRAVITY;
248 const float gd2 = g * d * d;
249 const float len = sqrt(h * h + d * d);
250
251 float v, alpha;
252 /* are we rolling? */
253 if (rolled) {
254 const float rollAngle = 3.0; /* angle to throw at for rolling, in degrees. */
255 alpha = rollAngle * torad;
256 const float theta = atan2(d, -h) - 2 * alpha;
257 const float k = gd2 / (len * cos(theta) - h);
258 if (k <= 0) /* impossible shot at any velocity */
259 return 0;
260 v = sqrt(k);
261 } else {
262 /* firstly try with the maximum speed possible */
263 v = speed;
264 const float k = (v * v * h + gd2) / (v * v * len);
265
266 /* check whether the shot's possible */
267 if (launched && k >= -1 && k <= 1) {
268 /* it is possible, so calculate the angle */
269 alpha = 0.5 * (atan2(d, -h) - acos(k));
270 } else {
271 /* calculate the minimum possible velocity that would make it possible */
272 alpha = 0.5 * atan2(d, -h);
273 v = sqrt(gd2 / (len - h));
274 }
275 }
276
277 /* calculate velocities */
278 const float vx = v * cos(alpha);
279 const float vy = v * sin(alpha);
280 VectorNormalizeFast(delta);
281 VectorScale(delta, vx, v0);
282 v0[2] = vy;
283
284 /* prevent any rounding errors */
286 VectorScale(v0, v - DIST_EPSILON, v0);
287
288 /* return time */
289 return d / vx;
290}
291
292/*
293============================================================================
294CLIENT / SERVER interactions
295============================================================================
296*/
297
298static char* rd_buffer;
299static unsigned int rd_buffersize;
300static struct net_stream* rd_stream;
301
308void Com_BeginRedirect (struct net_stream* stream, char* buffer, int buffersize)
309{
310 if (!buffer || !buffersize)
311 return;
312
314 rd_buffer = buffer;
315 if (buffersize > MAXPRINTMSG)
316 Com_Error(ERR_DROP, "redirect buffer may not be bigger than MAXPRINTMSG (%i)", MAXPRINTMSG);
317 rd_buffersize = buffersize;
318 rd_buffer[0] = '\0';
319}
320
326{
328
329 rd_stream = nullptr;
330 rd_buffer = nullptr;
331 rd_buffersize = 0;
332}
333
338void Com_vPrintf (const char* fmt, va_list ap)
339{
340 char msg[MAXPRINTMSG];
341
342 Q_vsnprintf(msg, sizeof(msg), fmt, ap);
343
344 /* redirect the output? */
345 if (rd_buffer) {
346 if ((strlen(msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) {
348 rd_buffer[0] = '\0';
349 }
350 Q_strcat(rd_buffer, sizeof(char) * rd_buffersize, "%s", msg);
351 return;
352 }
353
354 Con_Print(msg);
355
356 /* also echo to debugging console */
358
359 /* logfile */
361 if (!logfile.f) {
362 if (logfile_active->integer > 2)
364 else
366 }
367 if (logfile.f) {
368 /* strip color codes */
369 const char* output = msg;
370
371 if (output[strlen(output) - 1] == '\n') {
372 char timestamp[40];
373 Com_MakeTimestamp(timestamp, sizeof(timestamp));
374 FS_Write(timestamp, strlen(timestamp), &logfile);
375 FS_Write(" ", 1, &logfile);
376 }
377
378 FS_Write(output, strlen(output), &logfile);
379
380 if (logfile_active->integer > 1)
381 fflush(logfile.f); /* force it to save every time */
382 }
383 }
384}
385
386void Com_Printf (const char* const fmt, ...)
387{
388 va_list ap;
389
390 va_start(ap, fmt);
391 vPrintfPtr(fmt, ap);
392 va_end(ap);
393}
394
398void Com_DPrintf (int level, const char* fmt, ...)
399{
400 /* don't confuse non-developers with techie stuff... */
401 if (!developer)
402 return;
403
404 if (developer->integer == 1 || (developer->integer & level)) {
405 va_list ap;
406
407 va_start(ap, fmt);
408 vPrintfPtr(fmt, ap);
409 va_end(ap);
410 }
411}
412
417void Com_Error (int code, const char* fmt, ...)
418{
419 va_list argptr;
420 static char msg[MAXPRINTMSG];
421 static bool recursive = false;
422
423 if (recursive)
424 Sys_Error("recursive error after: %s", msg);
425 recursive = true;
426
427 va_start(argptr, fmt);
428 Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
429 va_end(argptr);
430
431 switch (code) {
432 case ERR_DISCONNECT:
433 Com_Printf("%s\n", msg);
434 CL_Drop();
435 recursive = false;
436 Com_Drop();
437 case ERR_DROP:
438 Com_Printf("********************\n");
439 Com_Printf("ERROR: %s\n", msg);
440 Com_Printf("********************\n");
442 SV_Shutdown("Server crashed.", false);
443 CL_Drop();
444 recursive = false;
445 Com_Drop();
446 default:
447 Com_Printf("%s\n", msg);
448 SV_Shutdown("Server fatal crashed", false);
449
450 /* send an receive net messages a last time */
451 NET_Wait(0);
452
454 if (pipefile.f != nullptr) {
457 }
458
459 CL_Shutdown();
461 Sys_Error("Shutdown");
462 }
463}
464
465void Com_Drop (void)
466{
467 throw comDrop_t();
468}
469
471{
472#ifdef DEBUG
473#if SDL_VERSION_ATLEAST(2, 0, 0)
474 SDL_MessageBoxData data;
475 SDL_MessageBoxButtonData okButton;
476 SDL_MessageBoxButtonData cancelButton;
477
478 OBJZERO(data);
479 OBJZERO(okButton);
480 OBJZERO(cancelButton);
481
482 okButton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
483 okButton.text = "Yes";
484 okButton.buttonid = 1;
485
486 cancelButton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
487 cancelButton.text = "No";
488 cancelButton.buttonid = 2;
489
490 const SDL_MessageBoxButtonData buttons[] = {okButton, cancelButton};
491 data.flags = SDL_MESSAGEBOX_ERROR;
492 data.title = "Error";
493 data.message = "Break into the debugger?";
494 data.numbuttons = lengthof(buttons);
495 data.buttons = buttons;
496 data.window = nullptr;
497
498 int buttonid = -1;
499 SDL_ShowMessageBox(&data, &buttonid);
500 if (buttonid == 1) {
502 }
503#endif
504#endif
505}
506
511void Com_Quit (void)
512{
513#ifdef DEDICATED_ONLY
514 Com_WriteConfigToFile("dedconfig.cfg");
515#else
516 Com_WriteConfigToFile("config.cfg");
517#endif
518
519 SV_Shutdown("Server quit.", false);
520 SV_Clear();
521 CL_Shutdown();
522
523 /* send an receive net messages a last time */
524 NET_Wait(0);
526 if (pipefile.f != nullptr) {
529 }
530 Sys_Quit();
531}
532
533
539{
540 return SV_GetServerState();
541}
542
547void Com_SetServerState (int state)
548{
549 Com_DPrintf(DEBUG_ENGINE, "Set server state to %i\n", state);
550 if (state == ss_dead)
551 SV_Shutdown("Server shutdown", false);
552 else if (state == ss_restart)
553 SV_Shutdown("Server map change", true);
554 sv->state = (server_state_t)state;
555}
556
560int Com_Argc (void)
561{
562 return com_argc;
563}
564
568const char* Com_Argv (int arg)
569{
570 if (arg < 0 || arg >= com_argc || !com_argv[arg])
571 return "";
572 return com_argv[arg];
573}
574
580void Com_ClearArgv (int arg)
581{
582 if (arg < 0 || arg >= com_argc || !com_argv[arg])
583 return;
584 com_argv[arg] = "";
585}
586
587static void Com_InitArgv (int argc, char** argv)
588{
589 if (argc > MAX_NUM_ARGVS)
590 Com_Error(ERR_FATAL, "argc > MAX_NUM_ARGVS");
591 com_argc = argc;
592 for (int i = 0; i < argc; i++) {
593 if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS)
594 com_argv[i] = "";
595 else
596 com_argv[i] = argv[i];
597 }
598}
599
600#define MACRO_CVAR_ID_LENGTH 6
607const char* Com_MacroExpandString (const char* text)
608{
609 static char expanded[MAX_STRING_CHARS];
610
611 const char* scan = text;
612 if (!text || !*text)
613 return nullptr;
614
615 const int len = strlen(scan);
616 if (len >= MAX_STRING_CHARS) {
617 Com_Printf("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
618 return nullptr;
619 }
620
621 bool inquote = false;
622 int count = 0;
623 OBJZERO(expanded);
624 char* pos = expanded;
625
626 /* also the \0 */
627 assert(scan[len] == '\0');
628 for (int i = 0; i <= len; i++) {
629 if (scan[i] == '"')
630 inquote ^= 1;
631 /* don't expand inside quotes */
632 if (inquote || strncmp(&scan[i], "*cvar:", MACRO_CVAR_ID_LENGTH)) {
633 *pos++ = scan[i];
634 continue;
635 }
636
637 /* scan out the complete macro and only parse the cvar name */
638 const char* start = &scan[i + MACRO_CVAR_ID_LENGTH];
639 const char* token = Com_Parse(&start);
640 if (!start)
641 continue;
642
643 /* skip the macro and the cvar name in the next loop */
645 i += strlen(token);
646 i--;
647
648 /* get the cvar value */
649 const char* cvarvalue = Cvar_GetString(token);
650 if (!cvarvalue) {
651 Com_Printf("Could not get cvar value for cvar: %s\n", token);
652 return nullptr;
653 }
654
655 const int j = strlen(cvarvalue);
656 if (strlen(pos) + j >= MAX_STRING_CHARS) {
657 Com_Printf("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
658 return nullptr;
659 }
660
661 /* copy the cvar value into the target buffer */
662 /* check for overflow is already done - so MAX_STRING_CHARS won't hurt here */
663 Q_strncpyz(pos, cvarvalue, j + 1);
664 pos += j;
665
666 if (++count == 100) {
667 Com_Printf("Macro expansion loop, discarded.\n");
668 return nullptr;
669 }
670 }
671
672 if (inquote) {
673 Com_Printf("Line has unmatched quote, discarded.\n");
674 return nullptr;
675 }
676
677 if (count)
678 return expanded;
679
680 return nullptr;
681}
682
683void Com_UploadCrashDump (const char* crashDumpFile)
684{
685 if (uploadcrashdump == nullptr || uploadcrashdump->integer != 1)
686 return;
687 upparam_t paramUser;
688 upparam_t paramVersion;
689 upparam_t paramOS;
690 const char* crashDumpURL = "https://ufoai.org/CrashDump.php";
691
692 paramUser.name = "user";
693 paramUser.value = Sys_GetCurrentUser();
694 paramUser.next = &paramVersion;
695 paramVersion.name = "version";
696 paramVersion.value = UFO_VERSION;
697 paramVersion.next = &paramOS;
698 paramOS.name = "os";
699 paramOS.value = BUILDSTRING_OS;
700 paramOS.next = nullptr;
701
702 HTTP_PutFile("crashdump", crashDumpFile, crashDumpURL, &paramUser);
703 HTTP_PutFile("crashdump", va("%s/%s", FS_Gamedir(), consoleLogName), crashDumpURL, &paramUser);
704}
705
717bool Com_ConsoleCompleteCommand (const char* s, char* target, size_t bufSize, uint32_t* pos, uint32_t offset)
718{
719 const char* cmd = nullptr, *cvar = nullptr, *use = nullptr;
720 char cmdLine[MAXCMDLINE] = "";
721 char cmdBase[MAXCMDLINE] = "";
722 bool append = true;
723
724 if (!s[0] || s[0] == ' ')
725 return false;
726
727 if (s[0] == '\\' || s[0] == '/') {
728 /* maybe we are using the same buffers - and we want to keep the slashes */
729 if (s == target)
730 offset++;
731 s++;
732 }
733
734 assert(bufSize <= MAXCMDLINE);
735 assert(pos);
736
737 /* don't try to search a command or cvar if we are already in the
738 * parameter stage */
739 if (strstr(s, " ")) {
740 Q_strncpyz(cmdLine, s, sizeof(cmdLine));
741 /* remove the last whitespace */
742 cmdLine[strlen(cmdLine) - 1] = '\0';
743
744 char* tmp = cmdBase;
745 while (*s != ' ')
746 *tmp++ = *s++;
747 /* get rid of the whitespace */
748 s++;
749 /* terminate the string at whitespace position to separate the cmd */
750 *tmp = '\0';
751
752 /* now strip away that part that is not yet completed */
753 tmp = strrchr(cmdLine, ' ');
754 if (tmp)
755 *tmp = '\0';
756
757 const int cntParams = Cmd_CompleteCommandParameters(cmdBase, s, &cmd);
758 if (cntParams > 1)
759 Com_Printf("\n");
760 if (cmd) {
761 /* append the found parameter */
762 Q_strcat(cmdLine, sizeof(cmdLine), " %s", cmd);
763 append = false;
764 use = cmdLine;
765 } else
766 return false;
767 } else {
768 /* Cmd_GenericCompleteFunction uses one static buffer for output, so backup one completion here if available */
769 static char cmdBackup[MAX_QPATH];
770 const int cntCmd = Cmd_CompleteCommand(s, &cmd);
771 if (cmd)
772 Q_strncpyz(cmdBackup, cmd, sizeof(cmdBackup));
773 const int cntCvar = Cvar_CompleteVariable(s, &cvar);
774
775 /* complete as much as possible, append only if one single match is found */
776 if (cntCmd > 0 && !cntCvar) {
777 use = cmd;
778 if (cntCmd != 1)
779 append = false;
780 } else if (!cntCmd && cntCvar > 0) {
781 use = cvar;
782 if (cntCvar != 1)
783 append = false;
784 } else if (cmd && cvar) {
785 const int maxLength = std::min(strlen(cmdBackup),strlen(cvar));
786 int idx = 0;
787 /* try to find similar content of cvar and cmd match */
788 Q_strncpyz(cmdLine, cmdBackup,sizeof(cmdLine));
789 for (; idx < maxLength; idx++) {
790 if (cmdBackup[idx] != cvar[idx]) {
791 cmdLine[idx] = '\0';
792 break;
793 }
794 }
795 if (idx == maxLength)
796 cmdLine[idx] = '\0';
797 use = cmdLine;
798 append = false;
799 }
800 }
801
802 if (use) {
803 Q_strncpyz(&target[offset], use, bufSize - offset);
804 *pos = strlen(target);
805 if (append)
806 target[(*pos)++] = ' ';
807 target[*pos] = '\0';
808
809 return true;
810 }
811
812 return false;
813}
814
816{
817 int i;
818
819 for (i = 0; i < csi.numGTs; i++) {
820 const gametype_t* gt = &csi.gts[i];
821 if (Q_streq(gt->id, sv_gametype->string)) {
822 int j;
823 const cvarlist_t* list;
825 Com_Printf("set gametype to: %s\n", gt->id);
826 for (j = 0, list = gt->cvars; j < gt->num_cvars; j++, list++) {
827 Cvar_Set(list->name, "%s", list->value);
829 Com_Printf(" %s = %s\n", list->name, list->value);
830 }
831 /*Com_Printf("Make sure to restart the map if you switched during a game\n");*/
832 break;
833 }
834 }
835
836 if (i == csi.numGTs)
837 Com_Printf("Can't set the gametype - unknown value for cvar gametype: '%s'\n", sv_gametype->string);
838}
839
840static void Com_GameTypeList_f (void)
841{
842 Com_Printf("Available gametypes:\n");
843 for (int i = 0; i < csi.numGTs; i++) {
844 int j;
845 const gametype_t* gt = &csi.gts[i];
846 const cvarlist_t* list;
847
848 Com_Printf("%s\n", gt->id);
849
850 for (j = 0, list = gt->cvars; j < gt->num_cvars; j++, list++)
851 Com_Printf(" %s = %s\n", list->name, list->value);
852 }
853}
854
861{
862 if (index < 0 || index >= MAX_CONFIGSTRINGS)
863 return false;
864
865 /* CS_TILES and CS_POSITIONS can stretch over multiple configstrings,
866 * so don't access the middle parts. */
867 if (index > CS_TILES && index < CS_POSITIONS)
868 return false;
870 return false;
871
872 return true;
873}
874
875#ifdef DEBUG
879static void Com_DebugHelp_f (void)
880{
881 Cvar_PrintDebugCvars();
882
883 Cmd_PrintDebugCommands();
884}
885
889static void Com_DebugError_f (void)
890{
891 if (Cmd_Argc() == 3) {
892 const char* errorType = Cmd_Argv(1);
893 if (Q_streq(errorType, "ERR_DROP"))
894 Com_Error(ERR_DROP, "%s", Cmd_Argv(2));
895 else if (Q_streq(errorType, "ERR_FATAL"))
896 Com_Error(ERR_FATAL, "%s", Cmd_Argv(2));
897 else if (Q_streq(errorType, "ERR_DISCONNECT"))
899 }
900 Com_Printf("Usage: %s <ERR_FATAL|ERR_DROP|ERR_DISCONNECT> <msg>\n", Cmd_Argv(0));
901}
902#endif
903
904
905typedef struct debugLevel_s {
906 const char* str;
909
910static const debugLevel_t debugLevels[] = {
911 {"DEBUG_ALL", DEBUG_ALL},
912 {"DEBUG_ENGINE", DEBUG_ENGINE},
913 {"DEBUG_SHARED", DEBUG_SHARED},
914 {"DEBUG_SYSTEM", DEBUG_SYSTEM},
915 {"DEBUG_COMMANDS", DEBUG_COMMANDS},
916 {"DEBUG_CLIENT", DEBUG_CLIENT},
917 {"DEBUG_EVENTSYS", DEBUG_EVENTSYS},
918 {"DEBUG_ROUTING", DEBUG_ROUTING},
919 {"DEBUG_SERVER", DEBUG_SERVER},
920 {"DEBUG_GAME", DEBUG_GAME},
921 {"DEBUG_RENDERER", DEBUG_RENDERER},
922 {"DEBUG_SOUND", DEBUG_SOUND},
923
924 {nullptr, 0}
925};
926
927static void Com_DeveloperSet_f (void)
928{
929 const int oldValue = Cvar_GetInteger("developer");
930 int newValue = oldValue;
931 int i = 0;
932
933 if (Cmd_Argc() == 2) {
934 const char* debugLevel = Cmd_Argv(1);
935 while (debugLevels[i].str) {
936 if (Q_streq(debugLevel, debugLevels[i].str)) {
937 if (oldValue & debugLevels[i].debugLevel) /* if it's already set... */
938 newValue &= ~debugLevels[i].debugLevel; /* ...reset it. */
939 else
940 newValue |= debugLevels[i].debugLevel;
941 break;
942 }
943 i++;
944 }
945 if (!debugLevels[i].str) {
946 Com_Printf("No valid debug mode parameter\n");
947 return;
948 }
949 Cvar_SetValue("developer", newValue);
950 Com_Printf("Currently selected debug print levels\n");
951 i = 0;
952 while (debugLevels[i].str) {
953 if (newValue & debugLevels[i].debugLevel)
954 Com_Printf("* %s\n", debugLevels[i].str);
955 i++;
956 }
957 } else {
958 Com_Printf("Usage: %s <debug_level>\n", Cmd_Argv(0));
959 Com_Printf(" valid debug_levels are:\n");
960 while (debugLevels[i].str) {
961 Com_Printf(" * %s\n", debugLevels[i].str);
962 i++;
963 }
964 }
965}
966
967#ifndef DEDICATED_ONLY
971static bool Com_CvarCheckMaxFPS (cvar_t* cvar)
972{
973 /* don't allow setting maxfps too low (or game could stop responding) */
974 return Cvar_AssertValue(cvar, 10, 1000, true);
975}
976#endif
977
982{
984
986 if (!f.file()) {
987 Com_Printf("Couldn't write %s.\n", filename);
988 return;
989 }
990
991 FS_Printf(&f, "// generated by ufo, do not modify\n");
992 FS_Printf(&f, "// variables\n");
994 FS_Printf(&f, "// aliases\n");
996 Com_Printf("Wrote %s.\n", filename);
997}
998
999void Com_SetRandomSeed (unsigned int seed)
1000{
1001 srand(seed);
1002 /*Com_Printf("setting random seed to %i\n", seed);*/
1003}
1004
1005const char* Com_ByteToBinary (byte x)
1006{
1007 static char buf[9];
1008 const int mask = 1 << 7;
1009 char* b = buf;
1010
1011 for (int cnt = 1; cnt <= 8; ++cnt) {
1012 *b++ = ((x & mask) == 0) ? '0' : '1';
1013 x <<= 1;
1014 if (cnt == 8)
1015 *b++ = '\0';
1016 }
1017
1018 return buf;
1019}
1020
1021const char* Com_UnsignedIntToBinary (uint32_t x)
1022{
1023 static char buf[37];
1024 const int mask = 1 << 31;
1025 char* b = buf;
1026
1027 for (int cnt = 1; cnt <= 32; ++cnt) {
1028 *b++ = ((x & mask) == 0) ? '0' : '1';
1029 x <<= 1;
1030 if (cnt % 8 == 0 && cnt != 32)
1031 *b++ = ' ';
1032 if (cnt == 32)
1033 *b++ = '\0';
1034 }
1035
1036 return buf;
1037}
1038
1042static void Com_WriteConfig_f (void)
1043{
1044 char filename[MAX_QPATH];
1045
1046 if (Cmd_Argc() != 2) {
1047 Com_Printf("Usage: %s <filename>\n", Cmd_Argv(0));
1048 return;
1049 }
1050
1051 Q_strncpyz(filename, Cmd_Argv(1), sizeof(filename));
1052 Com_DefaultExtension(filename, sizeof(filename), ".cfg");
1054}
1055
1056static void Cbuf_Execute_timer (int now, void* data)
1057{
1058 Cbuf_Execute();
1059}
1060
1062{
1063 vPrintfPtr = func;
1064}
1065
1067{
1068 return vPrintfPtr;
1069}
1070
1078void Qcommon_Init (int argc, char** argv)
1079{
1080 logfile_active = nullptr;
1081 developer = nullptr;
1082
1084
1085 /* random seed */
1086 Com_SetRandomSeed(time(nullptr));
1087
1088 com_aliasSysPool = Mem_CreatePool("Common: Alias system for commands and enums");
1089 com_cmdSysPool = Mem_CreatePool("Common: Command system");
1090 com_cmodelSysPool = Mem_CreatePool("Common: Collision model");
1091 com_cvarSysPool = Mem_CreatePool("Common: Cvar system");
1092 com_fileSysPool = Mem_CreatePool("Common: File system");
1093 com_genericPool = Mem_CreatePool("Generic");
1094 com_networkPool = Mem_CreatePool("Network");
1095
1096 try {
1097 OBJZERO(csi);
1098
1099 /* prepare enough of the subsystems to handle
1100 * cvar and command buffer management */
1101 Com_InitArgv(argc, argv);
1102
1103 Swap_Init();
1104 Cbuf_Init();
1105
1106 Cmd_Init();
1107 Cvar_Init();
1108
1109 uploadcrashdump = Cvar_Get("uploadcrashdump", "1", 0, "upload crashdumps to the developers");
1110
1111 Key_Init();
1112
1113 /* we need to add the early commands twice, because
1114 * a basedir needs to be set before executing
1115 * config files, but we want other parms to override
1116 * the settings of the config files */
1117 Cbuf_AddEarlyCommands(false);
1118 Cbuf_Execute();
1119
1120 FS_InitFilesystem(true);
1121
1122 Cbuf_AddText("exec default.cfg\n");
1123#ifdef DEDICATED_ONLY
1124 Cbuf_AddText("exec dedconfig.cfg\n");
1125#else
1126 Cbuf_AddText("exec config.cfg\n");
1127#endif
1128
1130 Cbuf_Execute();
1131
1132 Com_SetRenderModified(false);
1134
1135 /* init commands and vars */
1136 Cmd_AddCommand("saveconfig", Com_WriteConfig_f, "Write the configuration to file");
1137 Cmd_AddCommand("gametypelist", Com_GameTypeList_f, "List all available multiplayer game types");
1138#ifdef DEBUG
1139 Cmd_AddCommand("debug_help", Com_DebugHelp_f, "Show some debugging help");
1140 Cmd_AddCommand("debug_error", Com_DebugError_f, "Just throw a fatal error to test error shutdown procedures");
1141#endif
1142 Cmd_AddCommand("setdeveloper", Com_DeveloperSet_f, "Set the developer cvar to only get the debug output you want");
1143
1144 developer = Cvar_Get("developer", "0", 0, "Activate developer output to logfile and gameconsole");
1145#ifdef DEBUG
1146 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");
1147#else
1148 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");
1149#endif
1150 sv_gametype = Cvar_Get("sv_gametype", "fight1on1", CVAR_ARCHIVE | CVAR_SERVERINFO, "Sets the multiplayer gametype - see gametypelist command for a list of all gametypes");
1151 http_proxy = Cvar_Get("http_proxy", "", CVAR_ARCHIVE, "Use this proxy for http transfers");
1152 http_timeout = Cvar_Get("http_timeout", "3", CVAR_ARCHIVE, "Http connection and read timeout");
1154 masterserver_url = Cvar_Get("masterserver_url", MASTER_SERVER, CVAR_ARCHIVE, "URL of UFO:AI masterserver");
1155#ifdef DEDICATED_ONLY
1156 sv_dedicated = Cvar_Get("sv_dedicated", "1", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
1157 /* don't allow to override this from commandline of config */
1158 Cvar_ForceSet("sv_dedicated", "1");
1159#else
1160 sv_dedicated = Cvar_Get("sv_dedicated", "0", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
1161
1162 /* set this to false for client - otherwise Qcommon_Frame would set the initial values to multiplayer */
1163 sv_gametype->modified = false;
1164
1165 s_language = Cvar_Get("s_language", "", CVAR_ARCHIVE, "Game language - full language string e.g. en_EN.UTF-8");
1166 s_language->modified = false;
1167 cl_maxfps = Cvar_Get("cl_maxfps", "50", CVAR_ARCHIVE);
1169#endif
1170
1171 // 5 is an i7 with a medium gfx-card
1172 // 3 dual core with 2 GB
1173 // 2 EeePc with 1 GB
1174 // 1 smartphone
1175 const char* hwclassVal = "5";
1176#ifdef __ANDROID__
1178 hwclassVal = "1";
1179#endif
1180 hwclass = Cvar_Get("hwclass", hwclassVal, 0, "Defines the hardware class of this machine. 1 is the lowest, 5 is the highest.");
1181
1182 const char* s = va("UFO: Alien Invasion %s %s %s %s", UFO_VERSION, CPUSTRING, "Jul 20 2022", BUILDSTRING);
1183 Cvar_Get("version", s, CVAR_NOSET, "Full version string");
1184 Cvar_Get("ver", UFO_VERSION, CVAR_SERVERINFO | CVAR_NOSET, "Version number");
1185
1186 if (sv_dedicated->integer)
1187 Cmd_AddCommand("quit", Com_Quit, "Quits the game");
1188
1189 Mem_Init();
1190 Sys_Init();
1191
1192 NET_Init();
1193
1194#ifndef NO_HTTP
1195 curl_global_init(CURL_GLOBAL_NOTHING);
1196 Com_Printf("%s initialized.\n", curl_version());
1197#endif
1198
1199 SV_Init();
1200
1201 /* e.g. init the client hunk that is used in script parsing */
1202 CL_Init();
1203
1205#ifndef DEDICATED_ONLY
1206 Cbuf_AddText("exec keys.cfg\n");
1207#endif
1208
1209 if (!sv_dedicated->integer)
1210 Cbuf_AddText("init\n");
1211 else
1212 Cbuf_AddText("dedicated_start\n");
1213 Cbuf_Execute();
1214
1216
1217 /* add + commands from command line
1218 * if the user didn't give any commands, run default action */
1219 if (Cbuf_AddLateCommands()) {
1220 /* the user asked for something explicit
1221 * so drop the loading plaque */
1223 }
1224
1225 const cvar_t* com_pipefile = Cvar_Get("com_pipefile", "", CVAR_ARCHIVE, "Filename of the pipe that is used to send commands to the game");
1226 if (com_pipefile->string[0] != '\0') {
1227 FS_CreateOpenPipeFile(com_pipefile->string, &pipefile);
1228 }
1229
1230 CL_InitAfter();
1231
1232 /* Check memory integrity */
1234
1235#ifndef DEDICATED_ONLY
1236 if (!sv_dedicated->integer) {
1237 Schedule_Timer(cl_maxfps, &CL_Frame, nullptr, nullptr);
1238 Schedule_Timer(Cvar_Get("cl_slowfreq", "10", 0, nullptr), &CL_SlowFrame, nullptr, nullptr);
1239
1240 /* now hide the console */
1241 Sys_ShowConsole(false);
1242 }
1243#endif
1244
1245 Schedule_Timer(Cvar_Get("sv_freq", "10", CVAR_NOSET, nullptr), &SV_Frame, nullptr, nullptr);
1246
1248 Schedule_Timer(Cvar_Get("cbuf_freq", "10", 0, nullptr), &Cbuf_Execute_timer, nullptr, nullptr);
1249
1250 Com_Printf("====== UFO Initialized ======\n");
1251 Com_Printf("=============================\n");
1252 } catch (comDrop_t const&) {
1253 Sys_Error("Error during initialization");
1254 }
1255}
1256
1261{
1262 if (pipefile.f == nullptr)
1263 return;
1264
1265 char buffer[MAX_STRING_CHARS] = { "" };
1266 const int read = FS_Read2(buffer, sizeof(buffer), &pipefile, false);
1267 if (read > 0)
1268 Cmd_ExecuteString("%s", buffer);
1269}
1270
1271static void tick_timer (int now, void* data)
1272{
1273 struct timer* timer = (struct timer*)data;
1274 const int old_interval = timer->interval;
1275
1276 /* Compute and store the lateness, updating the total */
1277 const int lateness = Sys_Milliseconds() - now;
1280 timer->total_lateness += lateness;
1283
1284 /* Is it time to check the mean yet? */
1285 timer->next_check--;
1286 if (timer->next_check <= 0) {
1287 const int mean = timer->total_lateness / TIMER_LATENESS_HISTORY;
1288
1289 /* We use a saturating counter to damp the adjustment */
1290
1291 /* When we stay above the high water mark, increase the interval */
1292 if (mean > TIMER_LATENESS_HIGH)
1294 else
1295 timer->checks_high = std::max(0, timer->checks_high - 1);
1296
1298 timer->interval += 2;
1299
1300 /* When we stay below the low water mark, decrease the interval */
1301 if (mean < TIMER_LATENESS_LOW)
1303 else
1304 timer->checks_low = std::max(0, timer->checks_low - 1);
1305
1307 timer->interval -= 1;
1308
1309 /* Note that we slow the timer more quickly than we speed it up,
1310 * so it should tend to settle down in the vicinity of the low
1311 * water mark */
1312
1314 }
1315
1316 timer->interval = std::max(timer->interval, 1000 / timer->min_freq->integer);
1317
1318 if (timer->interval != old_interval)
1319 Com_DPrintf(DEBUG_ENGINE, "Adjusted timer on %s to interval %d\n", timer->min_freq->name, timer->interval);
1320
1321 try {
1322 timer->func(now, timer->data);
1323 } catch (comDrop_t const&) {
1324 }
1325
1326 /* We correct for the lateness of this frame. We do not correct for
1327 * the time consumed by this frame - that's billed to the lateness
1328 * of future frames (so that the automagic slowdown can work) */
1329 Schedule_Event(now + lateness + timer->interval, &tick_timer, nullptr, nullptr, timer);
1330}
1331
1332static void Schedule_Timer (cvar_t* freq, event_func* func, event_check_func* check, void* data)
1333{
1334 struct timer* const timer = Mem_PoolAllocType(struct timer, com_genericPool);
1335 timer->min_freq = freq;
1336 timer->interval = 1000 / freq->integer;
1337 timer->next_lateness = 0;
1338 timer->total_lateness = 0;
1340 timer->checks_high = 0;
1341 timer->checks_low = 0;
1342 timer->func = func;
1343 timer->data = data;
1344 for (int i = 0; i < TIMER_LATENESS_HISTORY; i++)
1345 timer->recent_lateness[i] = 0;
1346
1348}
1349
1363{
1365 event->when = when;
1366 event->func = func;
1367 event->check = check;
1368 event->clean = clean;
1369 event->data = data;
1370 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. */
1371 event->delay = nullptr;
1372
1373 eventQueue.insert(event);
1374
1375 return event;
1376}
1377
1383static size_t Delay_Events (int now, EventPriorityQueue::iterator i)
1384{
1385 const ScheduleEventPtr event = *i;
1386 EventPriorityQueue reOrder;
1387 EventPriorityQueue::iterator itEnd = eventQueue.end();
1388 for (; i != itEnd;) {
1389 ScheduleEventPtr tmpEvent = *i;
1390 if (tmpEvent->func != event->func) {
1391 ++i;
1392 continue;
1393 }
1394 if (tmpEvent->delay != nullptr && !tmpEvent->delay(now, tmpEvent->data)){
1395 ++i;
1396 continue;
1397 }
1398
1399 tmpEvent->when += event->delayFollowing;
1400 reOrder.insert(tmpEvent);
1401 eventQueue.erase(i++);
1402 }
1403 for (EventPriorityQueue::iterator r = reOrder.begin(); r != reOrder.end(); ++r) {
1404 eventQueue.insert(*r);
1405 }
1406 return reOrder.size();
1407}
1408
1416{
1417 for (EventPriorityQueue::iterator i = eventQueue.begin(); i != eventQueue.end(); ++i) {
1418 ScheduleEventPtr event = *i;
1419 if (event->when > now)
1420 break;
1421
1422 if (event->check == nullptr || event->check(now, event->data)) {
1423 eventQueue.erase(i);
1424 return event;
1425 }
1426
1427 /* delay all other events if this one is blocked */
1428 if (event->delayFollowing > 0) {
1429 if (Delay_Events(now, i) > 0) {
1430 if (event->notifyDelay != nullptr) {
1431 event->notifyDelay(now, event->notifyDelayUserData, event->delayFollowing);
1432 }
1433 break;
1434 }
1435 }
1436 }
1437 return ScheduleEventPtr();
1438}
1439
1447{
1448 int filtered = 0;
1449
1450 assert(filter);
1451
1452 for (EventPriorityQueue::iterator i = eventQueue.begin(); i != eventQueue.end();) {
1453 ScheduleEventPtr event = *i;
1454 const bool keep = filter(event->when, event->func, event->check, event->data);
1455 if (keep) {
1456 ++i;
1457 continue;
1458 }
1459
1460 if (event->clean != nullptr)
1461 event->clean(event->data);
1462
1463 EventPriorityQueue::iterator removeIter = i++;
1464 eventQueue.erase(removeIter);
1465 filtered++;
1466 }
1467
1468 return filtered;
1469}
1470
1480static bool Event_FilterAll (int when, event_func* func, event_check_func* check, void* data)
1481{
1482 return false;
1483}
1484
1493void Qcommon_Frame (void)
1494{
1495 try {
1496 /* If the next event is due... */
1498 if (event) {
1499 /* Dispatch the event */
1500 event->func(event->when, event->data);
1501 }
1502 } catch (comRestart_t const& restart) {
1503 SV_Shutdown("Restart.", false);
1504 CL_Shutdown();
1507 if (restart.gamedir != nullptr) {
1508 const char* restartArgv[] = {"", "+set", "fs_gamedir", restart.gamedir};
1509 Qcommon_Init(4, const_cast<char** >(restartArgv));
1510 } else {
1511 Qcommon_Init(0, nullptr);
1512 }
1513 } catch (comDrop_t const&) {
1514 return;
1515 }
1516
1517 /* Now we spend time_to_next milliseconds working on whatever
1518 * IO is ready (but always try at least once, to make sure IO
1519 * doesn't stall) */
1520 int time_to_next;
1521 do {
1522 time_to_next = !eventQueue.empty() ? (eventQueue.begin()->get()->when - Sys_Milliseconds()) : 1000;
1523 if (time_to_next < 0)
1524 time_to_next = 0;
1525
1526 NET_Wait(time_to_next);
1527 } while (time_to_next > 0);
1528}
1529
1538{
1539 HTTP_Cleanup();
1540
1541 FS_Shutdown();
1542 Cvar_Shutdown();
1543 Cmd_Shutdown();
1544 NET_Shutdown();
1545 Mem_Shutdown();
1546 Com_Shutdown();
1547}
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)
const char * Sys_GetCurrentUser(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 ...
Definition: cl_console.cpp:318
void FS_CloseFile(qFILE *f)
bool buttons[16]
Definition: cl_joystick.cpp:44
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)
Definition: cl_screen.cpp:277
bool operator()(const ScheduleEventPtr &e1, const ScheduleEventPtr &e2) const
Definition: common.cpp:98
const char * gamedir
Definition: common.h:248
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:1042
const char * Com_ByteToBinary(byte x)
Definition: common.cpp:1005
static struct net_stream * rd_stream
Definition: common.cpp:300
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:717
#define TIMER_CHECK_LAG
Definition: common.cpp:77
memPool_t * com_cmdSysPool
Definition: common.cpp:69
csi_t csi
Definition: common.cpp:39
cvar_t * s_language
Definition: common.cpp:54
static EventPriorityQueue eventQueue
Definition: common.cpp:104
int Com_Argc(void)
Returns the script commandline argument count.
Definition: common.cpp:560
#define TIMER_CHECK_INTERVAL
Definition: common.cpp:76
void Qcommon_Frame(void)
This is the function that is called directly from main()
Definition: common.cpp:1493
cvar_t * sys_os
Definition: common.cpp:61
#define TIMER_LATENESS_LOW
Definition: common.cpp:79
static const debugLevel_t debugLevels[]
Definition: common.cpp:910
memPool_t * com_cvarSysPool
Definition: common.cpp:71
#define MAX_NUM_ARGVS
Definition: common.cpp:37
static qFILE pipefile
Definition: common.cpp:66
static cvar_t * uploadcrashdump
Definition: common.cpp:63
void Com_SetServerState(int state)
Definition: common.cpp:547
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:1415
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:1332
#define TIMER_LATENESS_HIGH
Definition: common.cpp:78
void Com_ReadFromPipe(void)
Read whatever is in com_pipefile, if anything, and execute it.
Definition: common.cpp:1260
void Com_vPrintf(const char *fmt, va_list ap)
Definition: common.cpp:338
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:398
void Com_UploadCrashDump(const char *crashDumpFile)
Definition: common.cpp:683
int Com_ServerState(void)
Check whether we are the server or have a singleplayer tactical mission.
Definition: common.cpp:538
#define MACRO_CVAR_ID_LENGTH
Definition: common.cpp:600
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:971
static int com_argc
Definition: common.cpp:41
void Com_Quit(void)
Definition: common.cpp:511
void Qcommon_Init(int argc, char **argv)
Init function.
Definition: common.cpp:1078
static void Com_DeveloperSet_f(void)
Definition: common.cpp:927
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:231
void Com_WriteConfigToFile(const char *filename)
Definition: common.cpp:981
vPrintfPtr_t Qcommon_GetPrintFunction(void)
Definition: common.cpp:1066
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
void Com_SetGameType(void)
Definition: common.cpp:815
memPool_t * com_aliasSysPool
Definition: common.cpp:68
const char * Com_UnsignedIntToBinary(uint32_t x)
Definition: common.cpp:1021
static void Com_GameTypeList_f(void)
Definition: common.cpp:840
cvar_t * developer
Definition: common.cpp:46
void Com_SetRandomSeed(unsigned int seed)
Definition: common.cpp:999
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
memPool_t * com_networkPool
Definition: common.cpp:74
const char * Com_MacroExpandString(const char *text)
Expands strings with cvar values that are dereferenced by a '*cvar'.
Definition: common.cpp:607
std::multiset< ScheduleEventPtr, CompareScheduleEvent > EventPriorityQueue
Definition: common.cpp:103
static unsigned int rd_buffersize
Definition: common.cpp:299
static void Com_InitArgv(int argc, char **argv)
Definition: common.cpp:587
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:1362
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:1446
void Com_Drop(void)
Definition: common.cpp:465
void Com_BeginRedirect(struct net_stream *stream, char *buffer, int buffersize)
Redirect packets/output from server to client.
Definition: common.cpp:308
void Com_ClearArgv(int arg)
Reset com_argv entry to empty string.
Definition: common.cpp:580
bool Com_CheckConfigStringIndex(int index)
Definition: common.cpp:860
#define MAXPRINTMSG
Definition: common.cpp:36
void Com_EndRedirect(void)
End the redirection of packets/output.
Definition: common.cpp:325
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:1271
cvar_t * sv_gametype
Definition: common.cpp:56
static char * rd_buffer
Definition: common.cpp:298
static size_t Delay_Events(int now, EventPriorityQueue::iterator i)
Delay the following events and return the amount of events delayed.
Definition: common.cpp:1383
static qFILE logfile
Definition: common.cpp:65
void Com_BreakIntoDebugger(void)
Definition: common.cpp:470
static bool Event_FilterAll(int when, event_func *func, event_check_func *check, void *data)
Eventfilter that filter out all events.
Definition: common.cpp:1480
memPool_t * com_genericPool
Definition: common.cpp:73
void Qcommon_SetPrintFunction(vPrintfPtr_t func)
Definition: common.cpp:1061
memPool_t * com_cmodelSysPool
Definition: common.cpp:70
static void Cbuf_Execute_timer(int now, void *data)
Definition: common.cpp:1056
memPool_t * com_fileSysPool
Definition: common.cpp:72
static cvar_t * cl_maxfps
Definition: common.cpp:53
#define TIMER_LATENESS_HISTORY
Definition: common.cpp:80
const char * Com_Argv(int arg)
Returns an argument of script commandline.
Definition: common.cpp:568
void Qcommon_Shutdown(void)
Definition: common.cpp:1537
definitions common between client and server, but not game lib
void event_clean_func(void *data)
Definition: common.h:308
void(* vPrintfPtr_t)(const char *fmt, va_list ap)
Definition: common.h:285
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:329
#define PORT_SERVER
Definition: common.h:137
#define BUILDSTRING_OS
Definition: common.h:89
#define MASTER_SERVER
Definition: common.h:124
void event_func(int now, void *data)
Definition: common.h:300
#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:301
#define MAXCMDLINE
Definition: common.h:283
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:307
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
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
bool HTTP_PutFile(const char *formName, const char *fileName, const char *url, const upparam_t *params)
Definition: http.cpp:265
void HTTP_Cleanup(void)
UFO is exiting or we're changing servers. Clean up.
Definition: http.cpp:396
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:588
void Mem_Shutdown(void)
Definition: mem.cpp:603
#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
#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
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
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
int numGTs
Definition: q_shared.h:568
gametype_t gts[MAX_GAMETYPES]
Definition: q_shared.h:567
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition: cvar.h:71
bool modified
Definition: cvar.h:79
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:906
int debugLevel
Definition: common.cpp:907
cvarlist_t cvars[MAX_CVARLISTINGAMETYPE]
Definition: q_shared.h:344
char id[MAX_VAR]
Definition: q_shared.h:342
Definition: filesys.h:54
char name[MAX_OSPATH]
Definition: filesys.h:57
FILE * f
Definition: filesys.h:56
server_state_t state
Definition: server.h:107
Definition: common.cpp:82
cvar_t * min_freq
Definition: common.cpp:83
event_func * func
Definition: common.cpp:92
int next_lateness
Definition: common.cpp:86
int total_lateness
Definition: common.cpp:87
int interval
Definition: common.cpp:84
void * data
Definition: common.cpp:93
int recent_lateness[TIMER_LATENESS_HISTORY]
Definition: common.cpp:85
int next_check
Definition: common.cpp:88
int checks_low
Definition: common.cpp:90
int checks_high
Definition: common.cpp:89
Definition: http.h:59
struct upparam_s * next
Definition: http.h:62
const char * name
Definition: http.h:60
const char * value
Definition: http.h:61
void Sys_Breakpoint(void)
Definition: unix_shared.cpp:84
void Sys_InitSignals(void)
int Sys_Milliseconds(void)
Definition: unix_shared.cpp:41
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